Czy istnieje sposób przekazania dodatkowego argumentu do mojego AndroidViewModel
konstruktora niestandardowego z wyjątkiem kontekstu aplikacji. Przykład:
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);
}
}
A kiedy chcę ViewModel
użyć mojej niestandardowej klasy, używam tego kodu w moim fragmencie:
MyViewModel myViewModel = ViewModelProvider.of(this).get(MyViewModel.class)
Więc nie wiem, jak przekazać dodatkowy argument String param
do mojego niestandardowego ViewModel
. Mogę przekazać tylko kontekst aplikacji, ale nie dodatkowe argumenty. Naprawdę doceniłbym każdą pomoc. Dziękuję Ci.
Edycja: dodałem kod. Mam nadzieję, że teraz jest lepiej.
android
mvvm
viewmodel
android-components
Mario Rudman
źródło
źródło
Odpowiedzi:
Musisz mieć klasę fabryczną dla swojego ViewModel.
A podczas tworzenia wystąpienia modelu widoku postępujesz w następujący sposób:
W przypadku kotlin możesz użyć właściwości delegowanej:
Jest też inna nowa opcja - aby zaimplementować
HasDefaultViewModelProviderFactory
i nadpisaćgetDefaultViewModelProviderFactory()
za pomocą instancji fabryki, a następnie zadzwonić do fabrykiViewModelProvider(this)
lubby viewModels()
bez niej.źródło
ViewModel
klasa potrzebuje swojego ViewModelFactory?ViewModel
może / będzie miał inny DI. Skąd wiesz, które wystąpienie powróci docreate()
metody?ViewModel
stworzenie zapobiega metodzieget()
. Na podstawie dokumentacji: „Zwraca istniejący ViewModel lub tworzy nowy w zakresie (zwykle fragment lub działanie), powiązany z tym ViewModelProvider.” zobacz: developer.android.com/reference/android/arch/lifecycle/…return modelClass.cast(new MyViewModel(mApplication, mParam))
aby pozbyć się ostrzeżeniaZaimplementuj z iniekcją zależności
Jest to bardziej zaawansowane i lepsze dla kodu produkcyjnego.
Dagger2 , Square's AssistedInject oferuje gotową do produkcji implementację ViewModels, która może wprowadzać niezbędne komponenty, takie jak repozytorium obsługujące żądania sieciowe i bazy danych. Pozwala również na ręczne wprowadzanie argumentów / parametrów w aktywności / fragmencie. Oto zwięzły zarys kroków do wdrożenia z kodem Gists na podstawie szczegółowego postu Gabor Varadi, Dagger Tips .
Dagger Hilt to rozwiązanie nowej generacji, w wersji alfa od 12.07.2020, oferujące ten sam przypadek użycia z prostszą konfiguracją, gdy biblioteka jest w stanie wydania.
Wdrożenie z Lifecycle 2.2.0 w Kotlin
Przekazywanie argumentów / parametrów
Włączanie SavedState z argumentami / parametrami
źródło
W przypadku jednej fabryki współdzielonej przez wiele różnych modeli widoku rozszerzyłbym odpowiedź mlyko w ten sposób:
I tworzenie instancji modeli widoków:
Z różnymi modelami widoków posiadającymi różnych konstruktorów.
źródło
W oparciu o @ vilpe89 powyższe rozwiązanie Kotlin dla przypadków AndroidViewModel
}
Następnie fragment może zainicjować viewModel jako
A następnie rzeczywista klasa ViewModel
Lub jakąś odpowiednią metodą ...
źródło
Zrobiłem z tego klasę, w której przekazywany jest już utworzony obiekt.
I wtedy
źródło
Napisałem bibliotekę, która powinna uczynić to bardziej prostym i czystszym, bez konieczności stosowania wielu powiązań ani schematu fabrycznego, jednocześnie bezproblemowo pracując z argumentami ViewModel, które mogą być dostarczane jako zależności przez Dagger: https://github.com/radutopor/ViewModelFactory
W widoku:
źródło
(KOTLIN) Moje rozwiązanie wykorzystuje odrobinę Refleksji.
Powiedzmy, że nie chcesz tworzyć tej samej wyglądającej klasy Factory za każdym razem, gdy tworzysz nową klasę ViewModel, która wymaga pewnych argumentów. Możesz to osiągnąć poprzez refleksję.
Na przykład miałbyś dwie różne aktywności:
I modele widoków dla tych działań:
Następnie część magiczna, implementacja klasy Factory:
źródło
Dlaczego nie zrobić tego w ten sposób:
a następnie użyj go w ten sposób w dwóch krokach:
źródło
myViewModel.initialize(param)
wonCreate
aktywności, na przykład, może być wywołana wiele razy na tym samymMyViewModel
przykład, gdy użytkownik obraca urządzenie.Wywołaj Viewmodel w działaniu
Więcej informacji: Przykład systemu Android MVVM Kotlin
źródło