Método de pasar en contexto en ViewModel

ViewModelSe usa cada vez más, estrictamente hablando, el funcionario no recomienda que se le ViewModelagreguen Contextreferencias. Al mismo tiempo, ViewModelel 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 TestViewModelmé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 contextlos AndroidViewModelque 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.

Supongo que te gusta

Origin blog.csdn.net/Ser_Bad/article/details/111637963
Recomendado
Clasificación