Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Navigation Compose で 画面遷移実装を簡略化させる試み

nagayan
August 09, 2024

Navigation Compose で 画面遷移実装を簡略化させる試み

Android Navigation Compose で画面遷移時の引数を簡略化させる試みをしてみました。navitaion ライブラリの新しい機能である Type Safety を用いた、簡単な画面実装をご紹介します。

nagayan

August 09, 2024
Tweet

Other Decks in Technology

Transcript

  1. (C) Gunosy Inc. All Rights Reserved. PAGE | 2 ▪

    名前:nagayan / 永山 雄 ▪ 所属:株式会社Gunosy – Android エンジニア ▪ X:@nagayan_dev 自己紹介
  2. (C) Gunosy Inc. All Rights Reserved. PAGE | 3 アジェンダ

    • Navigation Compose の画面引数の基本実装 • 問題点 • Type safety の実装 • まとめ
  3. (C) Gunosy Inc. All Rights Reserved. PAGE | 5 Navigation

    Compose で引数が ある場合の基本的な設定方法 Navigation Compose の画面引数の基本実装 composable( route = "second_screen?pageId={pageId}", arguments = listOf( navArgument(name = "pageId") { type = NavType.LongType } ) ) { entry: NavBackStackEntry -> val pageId = entry.arguments?.getLong("pageId") SecondScreen(pageId) // Composable } navController.navigate(route = "second_screen?pageId=" + 100)
  4. (C) Gunosy Inc. All Rights Reserved. PAGE | 6 Navigation

    Compose の画面遷移 で必要な引数は、 URL のパラメー タのように route の文字列の後ろ に設定します。 Navigation Compose の画面引数の基本実装 composable( route = "second_screen?pageId={pageId}", arguments = listOf( navArgument(name = "pageId") { type = NavType.LongType } ) ) { entry: NavBackStackEntry -> val pageId = entry.arguments?.getLong("pageId") SecondScreen(pageId) }
  5. (C) Gunosy Inc. All Rights Reserved. PAGE | 7 arguments

    はリスト型で、引数に 入れたいオブジェクトの「型」情報 を入れる • navArgument メソッドで作成 ◦ name : key の文字列 ◦ type :引数の型 • プリミティブ型、文字列や Parcelable 型の指定が可能 Navigation Compose の画面引数の基本実装 composable( route = "second_screen?pageId={pageId}", arguments = listOf( navArgument(name = "pageId") { type = NavType.LongType } ) ) { entry: NavBackStackEntry -> val pageId = entry.arguments?.getLong("pageId") SecondScreen(pageId) }
  6. (C) Gunosy Inc. All Rights Reserved. PAGE | 8 NavBackStackEntry

    の arguments から値を取得する Navigation Compose の画面引数の基本実装 composable( route = "second_screen?pageId={pageId}", arguments = listOf( navArgument(name = "pageId") { type = NavType.LongType } ) ) { entry: NavBackStackEntry -> val pageId = entry.arguments?.getLong("pageId") SecondScreen(pageId) // Composable }
  7. (C) Gunosy Inc. All Rights Reserved. PAGE | 9 画面遷移元では、表示する画面の

    route に合わせて、文字列とパラ メータを設定する Navigation Compose の画面引数の基本実装 navController.navigate(route = "second_screen?pageId=" + 100) 画面遷移時に pageId = 100 を渡すことができる
  8. (C) Gunosy Inc. All Rights Reserved. PAGE | 11 問題点

    navController.navigate(route = "second_screen?url=https://tech.gunosy.io/") java.lang.IllegalArgumentException: Navigation destination that matches request NavDeepLinkRequest{~ • 引数に URL があるとエラーになってしまう • 引数が多くなると、route に複雑な文字列指定が必要となる route = "second_screen?pageId={pageId}&userId={userId}&url={url}&startDate={startDate}" java.lang.IllegalArgumentException: long does not allow nullable values • 引数を Nullable にできない型がある ◦ [Success] String、Array ◦ [Error] Long型, Boolean型等
  9. (C) Gunosy Inc. All Rights Reserved. PAGE | 13 Navigation

    Compose の Type safety こちらの API を使用していきます • androidx.navigation:navigation-*:2.8.0-alpha08 から型安全な Navigation API が提供されるようになった ◦ 最新は 2.8.0-beta07(8/7リリース) • データクラスやオブジェクトクラスを route に指定するだけで、簡単に 画面遷移することが可能
  10. (C) Gunosy Inc. All Rights Reserved. PAGE | 14 •

    画面遷移で渡したいデータ を定義します ◦ 渡したいデータなし:オ ブジェクトクラス ◦ 渡したいデータあり: データクラス • データ変換する関係で、 Serializable のアノテーショ ンが必要 オブジェクト・データクラスの作成 Type safety の実装 @Serializable @Parcelize data class SecondScreenData( val pageId: Long, val userId: Long?, val url: String, ) : Parcelable @Serializable object FirstScreenData 渡したいデータなし 渡したいデータあり
  11. (C) Gunosy Inc. All Rights Reserved. PAGE | 15 •

    NavHost 側の実装は右のよう になります 画面遷移先の実装 Type safety の実装 NavHost( navController = navController, startDestination = FirstScreenData ) { composable<FirstScreenData> { FirstScreen() } composable<SecondScreenData> { entry -> val data: SecondScreenData = entry.toRoute() SecondScreen(data) } }
  12. (C) Gunosy Inc. All Rights Reserved. PAGE | 16 •

    composable の型宣言のところ に、遷移時に渡したいオブジェク トクラス・データクラスを指定しま す • 最初の画面の場合は、NavHost の startDestination にクラスの 型を入れます 画面遷移先の実装 Type safety の実装 NavHost( navController = navController, startDestination = FirstScreenData ) { composable<FirstScreenData> { FirstScreen() } composable<SecondScreenData> { entry -> val data: SecondScreenData = entry.toRoute() SecondScreen(data) } }
  13. (C) Gunosy Inc. All Rights Reserved. PAGE | 17 •

    データクラスを渡した場合は、 NavBackStackEntry の toRoute メソッドで、データを取 得することができます 画面遷移先の実装 Type safety の実装 NavHost( navController = navController, startDestination = FirstScreenData ) { composable<FirstScreenData> { FirstScreen() } composable<SecondScreenData> { entry -> val data: SecondScreenData = entry.toRoute() SecondScreen(data) } }
  14. (C) Gunosy Inc. All Rights Reserved. PAGE | 18 •

    NavController クラスに新たに オブジェクトクラスやデータクラ スを指定できる navigate メソッ ドができている • 複雑な文字列を作成せず、設定 されているデータクラス等を入れ るだけで画面遷移が可能 画面遷移元の実装 Type safety の実装 val data = SecondScreenData( pageId = 100, // Long userId = null, // Long? url = "https://developer.android.com/guide/navigation/ design/type-safety" ) navController.navigate(route = data)
  15. (C) Gunosy Inc. All Rights Reserved. PAGE | 19 問題の解決状況

    問題 解決状況 引数が多くなると、route に複雑な文字列指定が必 要となる 解決 ◦:クラス1つでシンプル 引数に URL があるとエラーになってしまう 解決 ◦:エラーなし Long型や Boolean型等を Nullable にできない 解決 ◦:beta07 (8/7リリース)で改修さ れた 問題解決できました
  16. (C) Gunosy Inc. All Rights Reserved. PAGE | 20 Type

    safety を使わず、独自実装で対応したものがこちら • Android Navigation Compose で画面遷移時の引数を簡略化させる試 み ◦ https://tech.gunosy.io/entry/android_navigation_compose_simple_a rguments
  17. (C) Gunosy Inc. All Rights Reserved. PAGE | 22 まとめ

    • Navigation Compose で画面遷移時の引数を簡略化させる試み をしてみました • Type safety の実装を利用することで、1 つのクラスでシンプルな 画面遷移が可能になります • Type safety はまだ beta 版ではあるため、独自実装をしたい方 はブログを参照してください
  18. (C) Gunosy Inc. All Rights Reserved. PAGE | 23 エンジニア募集

    Gunosy では Android エンジニアを募集しております。 ご興味をお持ちの方はぜひご連絡ください! https://gunosy.co.jp/recruit/requirements/engineer