ViewModel
使用的越來(lái)越多了涣觉,嚴(yán)格來(lái)說(shuō)官册,官方并不建議你在ViewModel
中添加Context
的引用难捌。同時(shí),ViewModel
的構(gòu)造方法是沒有任何參數(shù)的员淫,有的時(shí)候會(huì)很不靈活击敌。以下記錄兩種方法。
1.通過(guò)kotlin的拓展函數(shù)
fun <T : ViewModelProvider, V : ViewModel> T.get(
key: String,
modelClass: Class<V>,
context: FragmentActivity
): V {
val model = get(key, modelClass)
if (model is TestViewModel) {
model.addContext(context)
}
return model
}
fun <T : ViewModelProvider, V : ViewModel> T.get(
key: String,
modelClass: Class<V>,
context: Context
): V {
val model = get(key, modelClass)
if (model is TestViewModel) {
model.addContext(context)
}
return model
}
fun <T : ViewModelProvider, V : ViewModel> T.get(
modelClass: Class<V>,
context: FragmentActivity
): V {
val model = get(modelClass)
if (model is TestViewModel) {
model.addContext(context)
}
return model
}
fun <T : ViewModelProvider, V : ViewModel> T.get(
modelClass: Class<V>,
context: Context
): V {
val model = get(modelClass)
if (model is TestViewModel) {
model.addContext(context)
}
return model
}
在TestViewModel
中添加如下的方法
class TestViewModel : ViewModel() {
protected lateinit var context: Context
open fun addContext(context: FragmentActivity) {
this.context = context
}
open fun addContext(context: Context) {
this.context = context
}
}
使用方法
val viewModel = ViewModelProvider(this).get(TestViewModel::class.java, this)
2.通過(guò)自定義ViewModelProvider.Factory
class CoreViewModelFactory(private val context: Context) : ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
try {
for (constructor in modelClass.constructors) {
if (arrayOf(Context::class.java).contentEquals(constructor.parameterTypes)) {
return (constructor as Constructor<T>).newInstance(context)
}
}
return modelClass.newInstance()
} catch (e: InstantiationException) {
throw RuntimeException("Cannot create an instance of $modelClass", e)
} catch (e: IllegalAccessException) {
throw RuntimeException("Cannot create an instance of $modelClass", e)
}
}
}
關(guān)于這一塊挤聘,仔細(xì)閱讀ViewModelProvider的代碼组去,會(huì)發(fā)現(xiàn)步淹,里面同樣提供了兩三種的Factory。針對(duì)可以直接擁有context
的AndroidViewModel
键闺,提供了ViewModelProvider.AndroidViewModelFactory
澈驼,只是在引用的時(shí)候尔艇,不要再自己添加一遍了。
以下是你的TestViewModel
class TestViewModel(private val context: Context) : ViewModel() {
init {
L.i(" context $context ")
}
}
使用方法
val viewModel = ViewModelProvider(this, CoreViewModelFactory(this)).get(TestViewModel::class.java)
以上兩種方法也可以用來(lái)幫助你自定義一些你要傳入的參數(shù)内边。