ViewModel
Se usa cada vez más, estrictamente hablando, el funcionario no recomienda que se le ViewModel
agreguen Context
referencias. Al mismo tiempo, ViewModel
el método de construcción no tiene ningún parámetro y, a veces, es muy inflexible. A continuación se registran dos métodos.
# 1. A través de la función de extensión de kotlin
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
}
En el TestViewModel
método, agregue lo siguiente
class TestViewModel : ViewModel() {
protected lateinit var context: Context
open fun addContext(context: FragmentActivity) {
this.context = context
}
open fun addContext(context: Context) {
this.context = context
}
}
Instrucciones
val viewModel = ViewModelProvider(this).get(TestViewModel::class.java, this)
# 2. A través de ViewModelProvider.Factory personalizado
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)
}
}
}
Con respecto a este, si lee el código de ViewModelProvider detenidamente, encontrará que también se proporcionan dos o tres tipos de Factory. Para context
los AndroidViewModel
que pueden ser de propiedad directa , se proporcionan ViewModelProvider.AndroidViewModelFactory
, pero no los vuelva a agregar cuando los cotice.
Abajo está el tuyoTestViewModel
class TestViewModel(private val context: Context) : ViewModel() {
init {
L.i(" context $context ")
}
}
Instrucciones
val viewModel = ViewModelProvider(this, CoreViewModelFactory(this)).get(TestViewModel::class.java)
Los dos métodos anteriores también se pueden usar para ayudarlo a personalizar algunos de los parámetros que desea pasar.