モケラ

Tech Sheets

mokelab

Jetpack Composeで画面遷移させる

最終更新日:2022-05-09

Jetpack Composeで画面遷移させるには、 NavHostを追加する の回で作成した NavController を使います。

まず、遷移先となる SecondScreen を作ります。

@Composable
fun SecondScreen() {
    Text("2nd Screen!!")
}

そして NavHost{} の中に追加します。今回は画面名を second にしてみます。

NavHost(navController = navController, startDestination = "main") {
    composable("main") {
        MainScreen()
    }
    // ここを追加
    composable("second") {
        SecondScreen()
    }
}

ボタンタップ時に画面遷移させてみたいので、 MainScreen にボタンを追加します。

@Composable
fun MainScreen() {
    Column {
        Text("Hello")
        Button(onClick = {
            /* later */
        }) {
            Text("Next")
        }
    }
}

ボタンタップ時に NavControllernavigate() が呼ばれるようにします。 MainScreen の引数に NavController を追加し、 onClick の中で呼びます。引数には遷移先となる画面名を指定します。

@Composable
fun MainScreen(navController: NavController) {
    Column {
        Text("Hello")
        Button(onClick = {
            navController.navigate("second")
        }) {
            Text("Next")
        }
    }
}

NavHost の部分も修正します。全体では次のようになります。

@Composable
fun MyApp() {
    ComposeAppTheme {
        val navController = rememberNavController()
        Scaffold(
            topBar = { MyTopAppBar() },
        ) {
            NavHost(navController = navController, startDestination = "main") {
                composable("main") {
                    // 引数としてnavControllerを渡す
                    MainScreen(navController = navController)
                }
                composable("second") {
                    SecondScreen()
                }
            }
        }
    }
}

これでボタンをタップすると SecondScreen に遷移し、端末のバックボタンで MainScreen に戻ってきます。

抽象化する

ここまで紹介した方法だと、 NavController が各画面に直接渡されます。これだとテスト時にやりづらくなるので、各画面はラムダ式を受け取るようにして抽象化を行います(公式ドキュメント

@Composable
fun MainScreen(toSecond: () -> Unit) {
    Column {
        Text("Hello")
        Button(onClick = {
            toSecond()
        }) {
            Text("Next")
        }
    }
}

NavHost の部分は次のようになります。

@Composable
fun MyApp() {
    ComposeAppTheme {
        val navController = rememberNavController()
        Scaffold(
            topBar = { MyTopAppBar() },
        ) {
            NavHost(navController = navController, startDestination = "main") {
                composable("main") {
                    MainScreen {
                        navController.navigate("second")
                    }
                }
                composable("second") {
                    SecondScreen()
                }
            }
        }
    }
}

一覧に戻る