8
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Jetpack Compose + HiltでViewModel生成時にパラメータを渡す

Last updated at Posted at 2024-02-03

概要

HiltはAndroidで公式に推奨されているDIライブラリです。Dagger 2.49で可能になった、ViewModel生成時に引数を動的に渡す方法(Assisted Injection)と、Jetpack Composeでの使用方法をまとめます。

Hiltの基本的な使い方

Hiltを使うと、依存関係はHiltが解決して生成してくれるので、ViewModelを生成する時に引数を渡す必要がありません。

@HiltViewModel
class MyViewModel @Inject constructor(
    private val repository: MyRepository// 依存オブジェクト
): ViewModel() {
    ...
}

@Composable
fun MyView(
    viewModel: MyViewModel = hiltViewModel()//引数を指定しなくていい
) {
    ...
}

しかし、ViewModelに追加のパラメータを渡したいとき、このような書き方はできません。

@HiltViewModel
class MyViewModel @Inject constructor(
    private val id: String,// 画面ごとに異なるID
    private val repository: MyRepository
): ViewModel() {
    ...
}

@Composable
fun MyView(
    viewModel: MyViewModel = hiltViewModel("id")// NG!
) {
    ...
}

そのため、SavedHandleStateを経由してパラメータを渡す方法などがありました。その場合、パラメータの受け渡しが散らばり、見通しが悪くなるという問題がありました。

Assisted Injection

Assisted InjectionはDIコンテナが管理していないパラメータを生成時に渡す方法です。ViewModelでAssisted Injectionを使うには問題がありましたが、Dagger 2.49で使えるようになりました。Jetpack Composeのための拡張は1.2.0-alpha01以降で対応しています。

build.gradle.kts
dependencies {
    ...
    implementation("androidx.hilt:hilt-navigation-compose:1.2.0-beta01")
    implementation("com.google.dagger:hilt-android:2.50")
    kapt("com.google.dagger:hilt-android-compiler:2.50")
    ...
}

ViewModelでAssisted Injectionを使うには、@Injectのかわりに@AssistedInjectを使い、追加で渡したい引数に@Assistedを付けます。

@HiltViewModel(assistedFactory = MyViewModelFactory::class)
class MyViewModel @AssistedInject constructor(
    @Assisted private val id: String,
    private val repository: MyRepository
): ViewModel() {
    ...
}

次にFactoryを定義します。Assistedなパラメータを引数に取る関数を定義するだけです。

@AssistedFactory
interface MyViewModelFactory {
    fun create(id: String) : MyViewModel
}

こうして、引数を渡してViewModelを生成することができます。hiltViewModel()に生成時コールバックが追加されています。

@Composable
fun Screen() {
    val viewModel = hiltViewModel(
        creationCallback = { factory: MyViewModelFactory ->
            factory.create("id")
        }
    )
    MyView(viewModel)
}

まとめ

SavedStateHandleに比べて、ViewModelにパラメータを渡すのが簡単になりました。
画面ごとに異なるパラメータを動的にViewModelに渡したい時は使えそうです。

参考

8
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?