Existe-t-il un moyen de passer un argument supplémentaire à mon AndroidViewModel
constructeur personnalisé à l' exception du contexte d'application. Exemple:
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);
}
}
Et quand je veux utiliser ma ViewModel
classe personnalisée , j'utilise ce code dans mon fragment:
MyViewModel myViewModel = ViewModelProvider.of(this).get(MyViewModel.class)
Donc je ne sais pas comment passer un argument supplémentaire String param
dans ma coutume ViewModel
. Je ne peux passer que le contexte d'application, mais pas d'arguments supplémentaires. J'apprécierais vraiment n'importe quelle aide. Je vous remercie.
Edit: j'ai ajouté du code. J'espère que c'est mieux maintenant.
android
mvvm
viewmodel
android-components
Mario Rudman
la source
la source
Réponses:
Vous devez avoir une classe d'usine pour votre ViewModel.
Et lors de l'instanciation du modèle de vue, procédez comme suit:
Pour kotlin, vous pouvez utiliser la propriété déléguée:
Il y a aussi une autre nouvelle option - pour implémenter
HasDefaultViewModelProviderFactory
et remplacergetDefaultViewModelProviderFactory()
avec l'instanciation de votre usine, puis vous appelleriezViewModelProvider(this)
ouby viewModels()
sans l'usine.la source
ViewModel
classe a- t-elle besoin de son ViewModelFactory?ViewModel
pourrait / aura un DI différent. Comment sauriez-vous quelle instance retourne sur lacreate()
méthode?ViewModel
création empêche la méthodeget()
. D'après la documentation: «Renvoie un ViewModel existant ou en crée un nouveau dans l'étendue (généralement, un fragment ou une activité), associé à ce ViewModelProvider.» voir: developer.android.com/reference/android/arch/lifecycle/…return modelClass.cast(new MyViewModel(mApplication, mParam))
pour se débarrasser de l'avertissementImplémenter avec l'injection de dépendances
C'est plus avancé et meilleur pour le code de production.
Dagger2 , Square's AssistedInject offre une implémentation prête pour la production pour ViewModels qui peut injecter les composants nécessaires tels qu'un référentiel qui gère les demandes de réseau et de base de données. Il permet également l'injection manuelle d'arguments / paramètres dans l'activité / le fragment. Voici un aperçu concis des étapes à mettre en œuvre avec le code Gists basé sur l'article détaillé de Gabor Varadi, Dagger Tips .
Dagger Hilt , est la solution de nouvelle génération, en version alpha à partir du 12/07/20, offrant le même cas d'utilisation avec une configuration plus simple une fois que la bibliothèque est en état de sortie.
Implémenter avec Lifecycle 2.2.0 dans Kotlin
Passer des arguments / paramètres
Activation de SavedState avec des arguments / paramètres
la source
Pour une usine partagée entre plusieurs modèles de vue différents, j'étendrais la réponse de mlyko comme suit:
Et instancier des modèles de vue:
Avec différents modèles de vue ayant différents constructeurs.
la source
Basé sur @ vilpe89, la solution Kotlin ci-dessus pour les cas AndroidViewModel
}
Ensuite, un fragment peut lancer le viewModel comme
Et puis la classe ViewModel réelle
Ou dans une méthode appropriée ...
la source
J'en ai fait une classe dans laquelle l'objet déjà créé est passé.
Puis
la source
J'ai écrit une bibliothèque qui devrait rendre cela plus simple et plus propre, pas de multibindings ou de passe-partout d'usine nécessaire, tout en travaillant de manière transparente avec les arguments ViewModel qui peuvent être fournis en tant que dépendances par Dagger: https://github.com/radutopor/ViewModelFactory
Dans la vue:
la source
(KOTLIN) Ma solution utilise un peu de réflexion.
Disons que vous ne voulez pas créer la même classe Factory à chaque fois que vous créez une nouvelle classe ViewModel qui a besoin de quelques arguments. Vous pouvez accomplir cela via Reflection.
Par exemple, vous auriez deux activités différentes:
Et ViewModels pour ces activités:
Puis la partie magique, l'implémentation de la classe Factory:
la source
Pourquoi ne pas le faire comme ça:
puis utilisez-le comme ceci en deux étapes:
la source
myViewModel.initialize(param)
àonCreate
l'activité, par exemple, il peut être appelé plusieurs fois sur le mêmeMyViewModel
exemple que l'utilisateur fait tourner le dispositif.Appeler Viewmodel en activité
Pour plus de référence: Exemple Android MVVM Kotlin
la source