Gibt es eine Möglichkeit, meinem benutzerdefinierten AndroidViewModel
Konstruktor außer dem Anwendungskontext zusätzliche Argumente zu übergeben? Beispiel:
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);
}
}
Und wenn ich meine benutzerdefinierte ViewModel
Klasse verwenden möchte, verwende ich diesen Code in meinem Fragment:
MyViewModel myViewModel = ViewModelProvider.of(this).get(MyViewModel.class)
Ich weiß also nicht, wie ich zusätzliche Argumente String param
in meinen Brauch übergeben soll ViewModel
. Ich kann nur den Anwendungskontext übergeben, aber keine zusätzlichen Argumente. Ich würde mich über jede Hilfe sehr freuen. Danke dir.
Bearbeiten: Ich habe Code hinzugefügt. Ich hoffe es ist jetzt besser.
android
mvvm
viewmodel
android-components
Mario Rudman
quelle
quelle
Antworten:
Sie benötigen eine Factory-Klasse für Ihr ViewModel.
Und wenn Sie das Ansichtsmodell instanziieren, gefällt Ihnen Folgendes:
Für Kotlin können Sie delegierte Eigenschaften verwenden:
Es gibt noch eine weitere neue Option: Implementieren
HasDefaultViewModelProviderFactory
und ÜberschreibengetDefaultViewModelProviderFactory()
mit der Instanziierung Ihrer Fabrik und dann würden Sie anrufenViewModelProvider(this)
oderby viewModels()
ohne die Fabrik.quelle
ViewModel
Benötigt jede Klasse ihre ViewModelFactory?ViewModel
könnte / wird einen anderen DI haben. Wie würden Sie wissen, welche Instanz diecreate()
Methode zurückgibt?ViewModel
Erstellung verhindert Methodeget()
. Basierend auf der Dokumentation: "Gibt ein vorhandenes ViewModel zurück oder erstellt ein neues im Bereich (normalerweise ein Fragment oder eine Aktivität), das diesem ViewModelProvider zugeordnet ist." siehe: developer.android.com/reference/android/arch/lifecycle/…return modelClass.cast(new MyViewModel(mApplication, mParam))
, um die Warnung loszuwerdenImplementieren Sie mit Abhängigkeitsinjektion
Dies ist weiter fortgeschritten und besser für den Produktionscode.
Dagger2 , das AssistedInject von Square, bietet eine produktionsbereite Implementierung für ViewModels, mit der erforderliche Komponenten wie ein Repository, das Netzwerk- und Datenbankanforderungen verarbeitet, eingefügt werden können. Es ermöglicht auch die manuelle Einfügung von Argumenten / Parametern in die Aktivität / das Fragment. Hier ist ein kurzer Überblick über die Schritte, die mit Code Gists implementiert werden müssen, basierend auf Gabor Varadis detailliertem Beitrag Dagger Tips .
Dagger Hilt ist die Lösung der nächsten Generation in Alpha ab dem 12.07.20. Sie bietet denselben Anwendungsfall mit einer einfacheren Einrichtung, sobald sich die Bibliothek im Release-Status befindet.
Implementieren Sie mit Lifecycle 2.2.0 in Kotlin
Argumente / Parameter übergeben
Aktivieren von SavedState mit Argumenten / Parametern
quelle
Für eine Fabrik, die von mehreren verschiedenen Ansichtsmodellen gemeinsam genutzt wird, würde ich die Antwort von mlyko folgendermaßen erweitern:
Und Ansichtsmodelle instanziieren:
Mit unterschiedlichen Ansichtsmodellen mit unterschiedlichen Konstruktoren.
quelle
Basierend auf @ vilpe89 die obige Kotlin-Lösung für AndroidViewModel-Fälle
}}
Dann kann ein Fragment das viewModel als initiieren
Und dann die eigentliche ViewModel-Klasse
Oder in einer geeigneten Methode ...
quelle
Ich habe es zu einer Klasse gemacht, in der das bereits erstellte Objekt übergeben wird.
Und dann
quelle
Ich habe eine Bibliothek geschrieben, die dies einfacher und sauberer machen soll, ohne dass Multibindings oder Factory Boilerplate erforderlich sind, während ich nahtlos mit ViewModel-Argumenten arbeite, die von Dagger als Abhängigkeiten bereitgestellt werden können: https://github.com/radutopor/ViewModelFactory
In der Ansicht:
quelle
(KOTLIN) Meine Lösung verwendet ein wenig Reflexion.
Nehmen wir an, Sie möchten nicht jedes Mal dieselbe Factory-Klasse erstellen, wenn Sie eine neue ViewModel-Klasse erstellen, für die einige Argumente erforderlich sind. Sie können dies über Reflection erreichen.
Zum Beispiel hätten Sie zwei verschiedene Aktivitäten:
Und ViewModels für diese Aktivitäten:
Dann der magische Teil, die Implementierung der Factory-Klasse:
quelle
Warum nicht so machen:
und verwenden Sie es dann in zwei Schritten:
quelle
myViewModel.initialize(param)
inonCreate
der Aktivität, zum Beispiel, kann es mehrere Male auf der gleichen aufgerufen wirdMyViewModel
Instanz wie der Benutzer das Gerät dreht.Rufen Sie Viewmodel in Activity auf
Weitere Informationen: Android MVVM Kotlin Beispiel
quelle