4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Android Jetpack Composeの画面遷移(NavController)

Last updated at Posted at 2023-06-28

Jetpack Composeの画面遷移

NavControllerを使用して、Composable間の画面遷移を行います。

環境

AndroidStudio:Flamingo | 2022.2.1 Patch 2
OS:macOS

Step1.ライブラリの追加

執筆時点(2023/6/28)での最新は2.6.0です。
navigation-composeを追加します。

dependencies {
    implementation platform('androidx.compose:compose-bom:2022.10.00')
    implementation 'androidx.compose.ui:ui'
    implementation 'androidx.compose.ui:ui-graphics'
    implementation 'androidx.compose.ui:ui-tooling-preview'
    implementation 'androidx.compose.material3:material3'
    implementation 'androidx.navigation:navigation-compose:2.6.0'
}

Step2.トップ画面と遷移先画面を作成

トップ画面には、遷移先画面へ移動するためのボタンを一つ作ります。
遷移先画面には、JetpackComposeのチュートリアルで作成したメッセージ一覧画面を流用します。

  • トップ画面
    ボタンを画面の真ん中に表示しています。
    IconButtonは、カスタムComposeです。
TopScreen.kt
@Composable
fun TopScreen(onNavigateToConversation: () -> Unit) {
    Surface(modifier = Modifier.fillMaxSize()) {
        Column(
            horizontalAlignment = Alignment.CenterHorizontally,
            modifier = Modifier.padding(8.dp),
            verticalArrangement = Arrangement.Center,
        ) {
            IconButton(label = "Greeting", onClick = onNavigateToConversation)
        }
    }
}
  • 遷移先画面
ConversationScreen.kt
@Composable
fun ConversationScreen() {
    Surface(modifier = Modifier.fillMaxSize()) {
        Conversation(SampleData.conversationSample)
    }
}

Step3.MainActivityに遷移情報を追加する

画面遷移は、navController.navigation("画面名")で行います。
画面名は、文字列直書きでいいんですが、個人的に、重複と文字列直書きがいやなので、enum classを作成して、そのnameプロパティを指定しています。

MainActivity.kt
setContent {
    ComposeTutorialTheme {
        val navController = rememberNavController()
        NavHost(navController = navController, startDestination = Nav.TopScreen.name) {
            composable(route = Nav.TopScreen.name) {
                TopScreen(
                    onNavigateToConversation = { navController.navigate(Nav.ConversationScreen.name) },
                )
            }
            composable(route = Nav.ConversationScreen.name) { ConversationScreen() }
        }
    }
}
Nav.kt
enum class Nav {
    TopScreen,
    ConversationScreen,
}

いざ実行

最初にボタン一つの画面が表示され、ボタンを押すと遷移先画面が表示されます。コードはこちら
navcontroller_AdobeExpress.gif

Step4.引数を渡す

トップ画面から遷移先画面に移動する際に、引数を渡します。
例として、タイトルとして表示する文字列と日時のミリ秒を渡し、遷移先画面の一番上に表示させてみます。

トップ画面から遷移先画面を呼び出す際、navController.navigateに引数として使用するroute名に「route名+"/"+引数+"/"+引数...」を指定します。(この値はURIと同じエスケープが必要です)

遷移先画面では、route名の変更(引数の追加)、引数の定義を行います。
型定義を省略した場合、すべて文字列として扱われます。

MainActivity.kt
composable(route = Nav.TopScreen.name) {
    val title = URLEncoder.encode("/\\ Conversationタイトル /\\", "UTF-8")
    val timeInMillis = System.currentTimeMillis()
    TopScreen(
        onNavigateToConversation = {
            navController.navigate("${Nav.ConversationScreen.name}/$title/$timeInMillis")
        },
    )
}
composable(
    route = "${Nav.ConversationScreen.name}/{title}/{time}",
    arguments = listOf(
        navArgument("title") { type = NavType.StringType },
        navArgument("time") { type = NavType.LongType },
    ),
) { backStackEntry ->
    val title = URLDecoder.decode(backStackEntry.arguments?.getString("title") ?: "", "UTF-8")
    val timeInMillis = backStackEntry.arguments?.getLong("time")
    ConversationScreen(title, timeInMillis)
}

いざ実行

遷移先画面の一番上に、文字列と数値(日時のミリ秒)が表示されました。コードはこちら
Screenshot_nav_args.png

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?