目次

06.共有ViewModelの作成

経路一覧編集画面から呼ばれる駅選択画面は、それぞれの間でデータの受け渡しがあります。

モジュール間のデータの受け渡しは、各画面固有のViewModelとは別に共有ViewModelを作成して行い、Lifecycle管理を容易にするため、DI(Hilt)を利用します。

また、プレビュー画面でプレビューする際にもViewModelが必要となりますが、プレビューではDI(Hilt)が利用できないため、プレビュー用のViewModelを別途作成しなければならず、ViewModelの差し替えが発生します。

ViewModelの差し替えをコードを変更することなく行うため、インターフェース定義でViewModelを抽象化した上で、実装したそれぞれのViewModelを使うようにします。

共通UIモジュールの準備

依存関係の循環がおきないよう、共有ViewModelは、:feature:depart:uiモジュールを準備して、その中に作成します。

共通UIモジュールの作成と同様に、トップディレクトリで:feature:depart:uiを作成し、javaディレクトリ名の変更、および、サンプルテストクラスの削除を行います。

LibraryConfigurePluginの適用

:feature:depart:uiモジュールのbuild.gradle.ktsにビルドプラグインを適用します。

plugins {
  alias(libs.plugins.android.library)
  alias(libs.plugins.kotlin.android)
  id("build.logic.library.configure")
  id("org.jetbrains.kotlin.plugin.compose")
}

android {
  namespace = "jp.co.progress_llc.portal.feature.depart.ui"
  compileSdk {
    version = release(36)
  }

  defaultConfig {
    minSdk = 28

    testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
    consumerProguardFiles("consumer-rules.pro")
  }

  buildTypes {
    release {
      isMinifyEnabled = false
      proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
    }
  }
  compileOptions {
    sourceCompatibility = JavaVersion.VERSION_11
    targetCompatibility = JavaVersion.VERSION_11
  }
  kotlinOptions {
    jvmTarget = "11"
  }
  buildFeatures {
    compose = true
  }
}

dependencies {

  implementation(libs.androidx.core.ktx)
  implementation(libs.androidx.appcompat)
  implementation(libs.material)
  testImplementation(libs.junit)
  androidTestImplementation(libs.androidx.junit)
  androidTestImplementation(libs.androidx.espresso.core)
  implementation(platform(libs.compose.bom))
  implementation(libs.compose.runtime)
  implementation(libs.hilt.android)
}

2行目~3行目、10行目~16行目、18行目~33行目、41行目~43行目
ビルドプラグインで定義しているので削除します。
4行目
/build-logic/build.gradle.ktsで定義したビルドプラグインのidを指定します。
5行目、34行目~36行目、47行目~48行目
Jetpack Composeを使用しますので追記します。
17行目、44行目~46行目
:feature:depart:uiモジュールではテストを行わないため削除します。
49行目
DI(Hilt)を使用しますので追記します。

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

ViewModelインターフェースの作成

:feature:depart:uiモジュールにviewmodelディレクトリ(パッケージ)を追加し、直下に駅選択画面と経路一覧編集画面間の共通ViewModelインターフェースDepartRouteEditViewModelContract.ktを作成します。

package jp.co.progress_llc.portal.feature.depart.ui.viewmodel

interface DepartRouteEditViewModelContract {
  var stationType: String
  var stationCode: String
  var stationName: String
}

4行目
駅の種別を定義しています。
5行目
駅コードを定義しています。
6行目
駅名を定義しています。

ViewModelインターフェースの実装

共通ViewModelインターフェースの実装をDepartRouteEditViewModel.ktで作成します。

package jp.co.progress_llc.portal.feature.depart.ui.viewmodel

import androidx.lifecycle.ViewModel
import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject

@HiltViewModel
class DepartRouteEditViewModel @Inject constructor()
  : ViewModel(), DepartRouteEditViewModelContract {
  override var stationType = ""
  override var stationCode = ""
  override var stationName = ""
}

7行目
DI(Hilt)の注入対象ViewModelであることを宣言しています。
10行目~12行目
インターフェースの各変数への初期化を実装しています。