2023年9月21日木曜日

Android つぶやきながらJetpackComposeのサンプルを覗いてみる その1

巷ではJetpackComposeが流行っているらしい。これまでAndroid開発では xml により画面のレイアウトを実装していたけど、今後は 宣言型UIフレームワーク が主流になってくる様子。xml が慣れている人にとってはまだすこし取っ掛かりにくいけど、画面の構成がより明示的に表現されるのであれば、それはそれで嬉しいと思う。

サンプルを見てみる。

Android Studio>File>New>Import Sample...で、入力フォームにcomposeを入力すると、それっぽいものがフィルタリングされるので、適当に選択する。Androidarchitecture>Architectureを選択してみる。(どうやらTODOアプリのサンプルが見れる様子。SunFlowerも画像表示のサンプルとしては重要だけど、今回はシンプルそうな方を眺めてみる)

とりあえずDLが終わったけどどこを見ればいいのかわからないので、AndroidManifest.xmlを見てみる。TodoActivity というActivityが登録してあるみたい。

TodoActivityを覗いてみる

override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  setContent {
    AppCompatTheme {
      TodoNavGraph()
    }
  }
}

setContentしか実装されていない... AppCompatThemeは名前からなんとなくテーマが設定されているコンポーネントかと予想できるので、その内側に設定されているTodoNavGraph を見てみる。(deprecatedなっていたが、趣旨から外れるのでここでは気にしないことにする。)

TodoNavGraphを覗いてみる

で、初っ端にでてきた実装がこれ。

@Composable
fun TodoNavGraph(
  modifier: Modifier = Modifier,
  navController: NavHostController = rememberNavController(),
  coroutineScope: CoroutineScope = rememberCoroutineScope(),
  drawerState: DrawerState = rememberDrawerState(initialValue = DrawerValue.Closed),
  startDestination: String = TodoDestinations.TASKS_ROUTE,
  navActions: TodoNavigationActions = remember(navController) {
    TodoNavigationActions(navController)
  }
) {
...

fun... メソッドやんけ...しかも戻り値もない...ほんとうにこれでいいんか...?もう少し眺めてみよう。

@Composableアノテーションが付与されたメソッド内の実装を眺めてみる。

どうやらNavHostというコンポーネント内で、必要なものを構成するぽい。

NavHost(
  navController = navController,
  startDestination = startDestination,
  modifier = modifier
) {

んで、その NavHost での実装は composable というコンポーネントで構成されている。

composable(
  TodoDestinations.TASKS_ROUTE,
  arguments = listOf( navArgument(USER_MESSAGE_ARG) { type = NavType.IntType; defaultValue = 0 }
  )
) { ... }
composable(TodoDestinations.STATISTICS_ROUTE) { ... }
composable(
  TodoDestinations.ADD_EDIT_TASK_ROUTE,
  arguments = listOf(
      navArgument(TITLE_ARG) { type = NavType.IntType },
      navArgument(TASK_ID_ARG) { type = NavType.StringType; nullable = true },
  )
) { ... }

で、そのコンポーネントが各画面やサイドメニュー(ドロワー)の要素に対応していそう。

まとめ(所感)

ここまでの所感など

  • TodoDestinations で定義された定数が、このアプリを構成する画面やドロワーに対応していそうに見える。であれば実際に運用する場合この定義は列挙型にしておいて、引数としてはordinalなどを渡してあげたほうが良さそうな。
  • TodoDestinations.ADD_EDIT_TASK_ROUTEcomposable を見ると、どうやら画面に渡すパラメータもここで定義しておく様子。ここでの定義と実際の画面とで乖離が起きないよう、画面側のどこかで管理しておいたほうが良さそう。
  • アプリを構成する画面定義は見えたけど、各画面間での画面遷移や処理結果の戻しなどをどのように実装するかは見えていないので、次にサンプルを眺めるときはこの辺りをフォーカスして確認できれば嬉しい。

とりあえずここまで。

参考

移行予定

どうも。どっことです。 タイトルの通りですが、諸事情により GitHubPage に移行予定です。 https://mkt120.github.io/ この備忘録に記載の内容を転記しつつ、今後はこちらのページを更新していく予定です。