目次

09.駅選択画面の表示

駅選択画面では共有ViewModelを使いますので、NavGraphの作成で必要な依存ライブラリを:feature:depart:stationモジュールのbuild.gradle.ktsに追記します。




   :
dependencies {
   :
  implementation(project(":core:navigation"))
  implementation(project(":feature:depart:navigation"))
   :
}

4行目
LocalNavControllerを使用するのでナビゲーションモジュールへの依存を追記します。
5行目
共有NavGraphの名称を使用するのでナビゲーションモジュールへの依存を追記します。

追記後、『Sync Now』で内容をプロジェクトに反映させます。

駅選択画面のNavGraphを作成

:feature:depart:stationモジュールにnavigationディレクトリ(パッケージ)を追加し、直下にDepartStationNavGraph.ktを作成します。

package jp.co.progress_llc.portal.feature.depart.station.navigation

import androidx.compose.runtime.remember
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.navigation.NavGraphBuilder
import androidx.navigation.compose.composable
import jp.co.progress_llc.portal.core.navigation.LocalNavController
import jp.co.progress_llc.portal.feature.depart.ui.viewmodel.DepartRouteEditViewModel
import jp.co.progress_llc.portal.feature.depart.station.presentation.DepartStationScreen
import jp.co.progress_llc.portal.feature.depart.navigation.DepartNavGraphName

const val DEPART_STATION = "depart_station"

fun NavGraphBuilder.departStationNavGraph() {
  composable(DEPART_STATION) { backStackEntry ->
    val navController = LocalNavController.current
    val parentEntry = remember(backStackEntry) {
      navController.getBackStackEntry(DepartNavGraphName.DEPART_ROUTE_EDIT)
    }
    val viewModel: DepartRouteEditViewModel = hiltViewModel(parentEntry)
    DepartStationScreen(departRouteEditViewModel = viewModel)
  }
}

12行目、15行目
発車予定の駅選択画面のNavGraph名を定義しています。
14行目~21行目
DepartStationScreenNavGraphに登録しています。
16行目~19行目
共有NavGraphスコープをBackStackから取得しています。
20行目
共有NavGraphスコープ内から型に一致するViewModelを取得しています。


※駅選択画面は、共有NavGraphでまとめて管理するため、駅選択画面のNavGraphDI(Hilt)に提供する必要はありません

経路一覧編集画面にナビゲーションへの依存を追記

駅選択画面は、発車予定モジュールの経路一覧編集画面から遷移しますので、:feature:depart:routeモジュールに駅選択画面への依存を追記します。

   :
dependencies {
   :
  implementation(project(":core:navigation"))
  implementation(project(":feature:depart:ui"))
  implementation(project(":feature:depart:station"))
   :
}

4行目
LocalNavControllerを使用するのでナビゲーションモジュールへの依存を追記します。
5行目
共有ViewModelを使用するのでUIモジュールへの依存を追記します。
6行目
駅選択画面への依存を追記します。

追記後、『Sync Now』で内容をプロジェクトに反映させます。

経路一覧編集画面に共有ViewModelと駅選択画面への遷移を追記

発車予定モジュールの経路一覧編集画面に駅選択画面への遷移を追記します。

   :
import androidx.navigation.NavController
import androidx.navigation.compose.rememberNavController
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
   :
import jp.co.progress_llc.portal.core.navigation.LocalNavController
import jp.co.progress_llc.portal.feature.depart.ui.viewmodel.DepartRouteEditViewModel
import jp.co.progress_llc.portal.feature.depart.ui.viewmodel.DepartRouteEditViewModelContract
import jp.co.progress_llc.portal.feature.depart.station.navigation.DEPART_STATION
   :
fun DepartRouteScreen() {
fun DepartRouteScreen(
  navController: NavController = LocalNavController.current,
  departRouteEditViewModel:
    DepartRouteEditViewModelContract = hiltViewModel<DepartRouteEditViewModel>()
) {
   :
          CustomOutlinedTextField(
            value = departureStation,
   :
            readOnly = true,
            onClick = {
              departRouteEditViewModel.stationType = FieldName.DEPARTURE
              navController.navigate(DEPART_STATION)
            },
   :
          CustomOutlinedTextField(
            value = viaStation,
   :
            readOnly = true,
            onClick = {
              departRouteEditViewModel.stationType = FieldName.VIA
              navController.navigate(DEPART_STATION)
            },
   :
          CustomOutlinedTextField(
            value = arrivalStation,
   :
            readOnly = true,
            onClick = {
              departRouteEditViewModel.stationType = FieldName.ARRIVAL
              navController.navigate(DEPART_STATION)
            },
   :
fun DepartRouteScreenPreview() {
  AppTheme {
   DepartRouteScreen()
    val previewNavController: NavController = rememberNavController()
    DepartRouteScreen(
      navController = previewNavController,
      departRouteEditViewModel = object : DepartRouteEditViewModelContract {
        override var stationType = ""
        override var stationCode = ""
        override var stationName = ""
      }
    )
   :

2行目~4行目、6行目~8行目
必要なimportを追記します。
11行目~16行目
LocalNavControllerからNavControllerrを取得します。
共有ViewModelのインタフェースを引数にしています。
既定でDI(Hilt)で共有ViewModelを注入しています。
22行目~25行目、31行目~34行目、40行目~43行目
テキストボックスがクリックされたらときの処理を追記します。
共有ViewModelにクリックされたテキストボックスの駅の型を格納し、駅選択画面に遷移させます。
47行目~56行目
画面の引数が増えたのでプレビューも対応します。

経路一覧編集画面のNavGraphを共有ViewModelを使用するように変更

経路一覧編集画面のNavGraphを共有ViewModelを使用するよう全面的に書き換えます。

package jp.co.progress_llc.portal.feature.depart.route.navigation

import androidx.compose.runtime.remember
import androidx.navigation.NavGraphBuilder
import androidx.navigation.compose.composable
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import jp.co.progress_llc.portal.core.navigation.LocalNavController
import jp.co.progress_llc.portal.feature.depart.ui.viewmodel.DepartRouteEditViewModel
import jp.co.progress_llc.portal.feature.depart.navigation.DepartNavGraphName
import jp.co.progress_llc.portal.feature.depart.route.presentation.DepartRouteScreen

internal const val DEPART_ROUTE = "depart_route"

fun NavGraphBuilder.departRouteNavGraph() {
  composable(DEPART_ROUTE) { backStackEntry ->
    val navController = LocalNavController.current
    val parentEntry = remember(backStackEntry) {
      navController.getBackStackEntry(DepartNavGraphName.DEPART_ROUTE_EDIT)
    }
    val viewModel: DepartRouteEditViewModel = hiltViewModel(parentEntry)
    DepartRouteScreen(departRouteEditViewModel = viewModel)
  }
}

3行目~10行目
必要なimportを追記しています。
16行目~21行目
共有NavGraphのスコープから共有ViewModelを取得して、DepartRouteScreenに渡します。


※経路一覧編集画面は、共有NavGraphでまとめて管理するため、経路一覧編集画面のNavGraphDI(Hilt)に提供する必要はありません

共有NavGraphに共有対象のNavGraphを追記

共有NavGraphViewModelを共有する駅選択画面のNavGraphを追記します。

   :
import jp.co.progress_llc.portal.feature.depart.station.navigation.departStationNavGraph
   :
fun NavGraphBuilder.departRouteEditNavGraph() {
   :
    departRouteNavGraph()
    departStationNavGraph()
   :

2行目
追記するNavGraphimportを追記しています。
7行目
共有対象のNavGraphを追記しています。

エミュレーターでアプリケーションを実行して、画面遷移で発車予定表示機能の駅選択画面が表示されることを確認します。