Android Architecture Components の ViewModel
を
Fragment
で取得するときは こう書くと思います:
import android.support.v4.app.Fragment
import androidx.lifecycle.ViewModelProviders
class MainFragment : Fragment() {
private lateinit var viewModel : MainViewModel
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
viewModel = ViewModelProviders.of(this).get(MainViewModel::class.java)
}
}
Fragment KTX を使うと
Property Delegate を使ってこうかけます:
import android.support.v4.app.Fragment
import androidx.fragment.app.viewModels
class MainFragment : Fragment() {
private val viewModel: MainViewModel by viewModels()
}
lateinit var
が val
になったので
なんとなく安心感が出てきましたね。
あるいは Activity
のスコープの ViewModel
をつかうときは
by activityViewModels
がつかえます:
import android.support.v4.app.Fragment
import androidx.fragment.app.activityViewModels
class MainFragment : Fragment() {
private val viewModel : MainViewModel by activityViewModels()
}
導入法
アプリ (モジュール) 以下の gradle に
Fragment KTX の依存を追加します:
dependencies {
implementation 'androidx.fragment:fragment-ktx:1.1.0-alpha04'
}
KTX について詳しくはこちら:
https://developer.android.com/kotlin/ktx
パターン
この Property Delegate は 2 つの引数をとりますが、
それぞれデフォルト引数が設定されてるのでなしでもいけますし、
指定してもいけるっていう便利な感じになってます。
inline fun <reified VM : ViewModel> Fragment.viewModels(
noinline ownerProducer: () -> ViewModelStoreOwner = { this },
noinline factoryProducer: (() -> Factory)? = null
)
これを踏まえてよく使うパターンが紹介されてます
1. 引数なし: by viewmodels()
1 つめは by viewmodels()
で引数なしで移譲するパターンです:
private val viewModel: MainViewModel by viewModels()
Returns a property delegate to access ViewModel by default scoped to this Fragment
このパターンでは、この ViewModel
のスコープが
このプロパティを定義した Fragment
( === this
) になります。
2. by viewmodels({ViewModelStoreOwner})
2 つめは by viewmodels ({requireParentFragment()})
のように
親の Fragment
を与えたりして、
別の Fragment
を ViewModel
のスコープとして与えることができます。
3. by viewmodels { ViewModelProvider.Factory }
3 つめは by viewmodels { myFactory }
として
ViewModel
を作成するようなファクトリのインスタンスを与えるパターンです。
これは Dagger で ViewModelProvider.Factory
を @Inject
するケースで使えますね。
両方の引数を与えたときはどちらも考慮される感じです:
https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-master-dev/lifecycle/viewmodel/ktx/src/main/java/androidx/lifecycle/ViewModelProvider.kt#54
べんり!