¿Hay alguna forma de pasar un argumento adicional a mi AndroidViewModel
constructor personalizado, excepto el contexto de la aplicación? Ejemplo:
public class MyViewModel extends AndroidViewModel {
private final LiveData<List<MyObject>> myObjectList;
private AppDatabase appDatabase;
public MyViewModel(Application application, String param) {
super(application);
appDatabase = AppDatabase.getDatabase(this.getApplication());
myObjectList = appDatabase.myOjectModel().getMyObjectByParam(param);
}
}
Y cuando quiero usar mi ViewModel
clase personalizada , uso este código en mi fragmento:
MyViewModel myViewModel = ViewModelProvider.of(this).get(MyViewModel.class)
Entonces no sé cómo pasar argumentos adicionales String param
a mi costumbre ViewModel
. Solo puedo pasar el contexto de la aplicación, pero no los argumentos adicionales. Realmente apreciaria cualquier ayuda. Gracias.
Editar: he agregado un código. Espero que esté mejor ahora.
android
mvvm
viewmodel
android-components
Mario Rudman
fuente
fuente
Respuestas:
Necesita tener una clase de fábrica para su ViewModel.
Y al crear una instancia del modelo de vista, te gusta esto:
Para kotlin, puede usar propiedad delegada:
También hay otra opción nueva: implementar
HasDefaultViewModelProviderFactory
y anulargetDefaultViewModelProviderFactory()
con la creación de instancias de su fábrica y luego llamaríaViewModelProvider(this)
oby viewModels()
sin la fábrica.fuente
ViewModel
clase necesita su ViewModelFactory?ViewModel
podría / tendrá diferente DI. ¿Cómo sabría qué instancia devuelve elcreate()
método?ViewModel
creación impide el métodoget()
. Basado en documentación: "Devuelve un ViewModel existente o crea uno nuevo en el alcance (generalmente, un fragmento o una actividad), asociado con este ViewModelProvider". ver: developer.android.com/reference/android/arch/lifecycle/…return modelClass.cast(new MyViewModel(mApplication, mParam))
Implementar con inyección de dependencia
Esto es más avanzado y mejor para el código de producción.
Dagger2 , AssistedInject de Square ofrece una implementación lista para producción para ViewModels que puede inyectar los componentes necesarios, como un repositorio que maneja las solicitudes de la red y la base de datos. También permite la inyección manual de argumentos / parámetros en la actividad / fragmento. Aquí hay un resumen conciso de los pasos para implementar con Code Gists basado en la publicación detallada de Gabor Varadi, Dagger Tips .
Dagger Hilt , es la solución de próxima generación, en alfa a partir del 12/7/20, que ofrece el mismo caso de uso con una configuración más simple una vez que la biblioteca está en estado de lanzamiento.
Implementar con Lifecycle 2.2.0 en Kotlin
Pasar argumentos / parámetros
Habilitación de SavedState con argumentos / parámetros
fuente
Para una fábrica compartida entre múltiples modelos de vista diferentes, extendería la respuesta de mlyko de esta manera:
E instanciar modelos de vista:
Con diferentes modelos de vista que tienen diferentes constructores.
fuente
Basado en @ vilpe89, la solución de Kotlin anterior para casos de AndroidViewModel
}
Entonces un fragmento puede iniciar viewModel como
Y luego la clase ViewModel real
O en algún método adecuado ...
fuente
Lo convertí en una clase en la que se pasa el objeto ya creado.
Y entonces
fuente
Escribí una biblioteca que debería hacer que hacer esto sea más sencillo y más limpio, sin necesidad de múltiples enlaces o repetición de fábrica, mientras trabajaba sin problemas con los argumentos de ViewModel que Dagger puede proporcionar como dependencias: https://github.com/radutopor/ViewModelFactory
En la vista:
fuente
(KOTLIN) Mi solución usa un poco de Reflexión.
Supongamos que no desea crear la misma clase Factory con el mismo aspecto cada vez que crea una nueva clase ViewModel que necesita algunos argumentos. Puede lograr esto a través de Reflection.
Por ejemplo, tendría dos actividades diferentes:
Y ViewModels para esas actividades:
Luego, la parte mágica, la implementación de la clase Factory:
fuente
Por qué no hacerlo así:
y luego úselo así en dos pasos:
fuente
myViewModel.initialize(param)
aonCreate
la actividad, por ejemplo, se puede llamar varias veces en la mismaMyViewModel
instancia cuando el usuario gira el dispositivo.Llamar a Viewmodel en actividad
Para más referencia: Ejemplo de Android MVVM Kotlin
fuente