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
べんり!