目次

目次

【Android】Composeのナビゲーションを使ってみる

アバター画像
黒滝理帆
アバター画像
黒滝理帆
最終更新日2024/04/16 投稿日2024/04/16

はじめに

Androidアプリ開発グループの黒滝です。 グループ名の通り日々Androidアプリを開発しており、Android開発歴は5年目になります。

この度、ライブラリのサンプルアプリを作成しました。 ごく少数しか使わない社内用のサンプルアプリということで開発は自分ひとり。 それなら色々と試してみようと思いComposeのナビゲーションを使ってみたので、その導入方法をまとめていきます。

実装

構成

本記事では、「画面1でボタンを押したら、画面2に遷移する」という簡単なアプリを作ります

  • class MainActivity
    • Navigationの遷移処理をする
  • fun FirstScreen()
    • Composeで作る画面1
  • fun SecondScreen()
    • Composeで作る画面2
  • sealed class ScreenNav
    • 後述のroute名の指定を楽にするために作成
    • なくても問題ない

implementationの追加

Composeでのナビゲーションを使うために以下を追加します

implementation("androidx.navigation:navigation-compose:2.5.0")

画面の作成

画面1は画面2に遷移するボタンのみ、画面2はテキストのみにします

画面.png
  • 画面1
@Composable
fun FirstScreen(navController: NavController) { // navControllerは後で使います
    Button(
        onClick = { } // TODO onClickの中身も後で紹介します
    ) {
        Text(text = "Go to SecondScreen")
    }
}
  • 画面2
@Composable
fun SecondScreen() {
    Text(
        text = "Hello world!",
        modifier = Modifier
    )
}

遷移処理の作成: Navigationの設定

まずMainActivityのonCreateで、Navigationの設定をしていきます。

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            val navController = rememberNavController() // 1
            Surface(
                modifier = Modifier.fillMaxSize()
            ) {
                NavHost( // 2
                    navController = navController, // 3
                    startDestination = ScreenNav.FirstScreenNav.route // 4
                ) {
                    composable(ScreenNav.FirstScreenNav.route) { // 5
                        FirstScreen(navController)
                    }
                    composable(ScreenNav.SecondScreenNav.route) { // 6
                        SecondScreen()
                    }
                }
            }
        }
    }
}
sealed class ScreenNav(val route: String) {
    object FirstScreenNav : ScreenNav("firstScreen")
    object SecondScreenNav : ScreenNav("secondScreen")
}
  1. setContent内にval navController = rememberNavControllerを作成する
  2. 1の下にNavHostを作成する
  3. 引数のnavControllerに1で作成したnavControllerを設定する
  4. 最初の画面として、引数のstartDestinationに画面1のroute名を設定する
    • startDestinationは文字列でどの画面か認識するので、"firstScreen"と書いても問題ない
    • ただタイポしてしまってもエラーにならないので、sealed class ScreenNavを作成し、ScreenNav.FirstScreenNav.routeを使うようにした
  5. composableで画面1の設定をする
    • composable(route名){画面や実行する処理}
    • ScreenNav.FirstScreenNav.routeが呼ばれたときに、FirstScreenを実行する」となっている
  6. 同様に画面2の設定をする

遷移処理の作成: ボタンが押されたときの挙動

次に画面1でボタンが押されたときの挙動を、FirstScreenのonClickに実装していきます。

@Composable
fun FirstScreen(navController: NavController) {
    Button(
        onClick = { navController.navigate(ScreenNav.SecondScreenNav.route) } // 1
    ) {
        Text(text = "Go to SecondScreen")
    }
}
  1. ButtonのonClickにて、navController.navigate(遷移先のroute名)とする

実際の動き

以上でコードを書き終えたので、実行するとこのように動きます。

  1. 画面1のボタンを押す
  2. onClickのnavController.navigate(ScreenNav.SecondScreenNav.route)を実行する
  3. NavHost内のScreenNav.SecondScreenNav.routeが設定されてるcomposableをみる
  4. SecondScreen()を実行する
  5. 画面2が表示される

Navigation GraphとComposeのNavigation

今まではNavigation Graphを使って画面遷移をしていました。 今回ComposeのNavigationを触ってみて、Navigation Graphから切り替えると考えたときのメリデメを少し上げます。

メリット

  • Kotlinで完結できる
    • XMLで画面とグラフを作って、KotlinでFragmentと遷移処理を作って。と分けなくて良くなる
  • 遷移先が同じときに新しくアクションを作らなくていい
    • 今まではFragmentAが遷移先の時、FragmentBからの遷移と、FragmentCからの遷移は別のactionが必要だった
    • Composeの場合は1つで良い

デメリット

  • 遷移図がないのが直感的に分かりづらい
  • 今回はシンプルな2画面だったが、一般的なアプリのように複雑な画面が何十個もある場合はNavHost内が複雑になりそう
    • 今回は触れなかったが引数を取れるので、複雑さが増しそう

終わりに

Composeでの画面作成はしたことがあったものの、Navigationはまだ使ったことがありませんでした。 今回触ってみて、既存のアプリに一度に導入するのは難しそうだなと思いつつ、アプリを一から作り始めるのであれば使いやすいかもなと思いました。

ここまでお読みいただき、ありがとうございました。

アバター画像

黒滝理帆

目次