Как получить ViewModel без класса ViewModelProviders?
Относительно прошлого вопроса Как получить ViewModel? и примеры, которые я нашел, это не решает мой случай. У меня нет разрешения комментировать там, поэтому я должен спросить еще раз. У меня нет класса ViewModelProviders, который я хотел бы использовать метод "of", как во всех примерах и документации, которые я нашел, например,
model = ViewModelProviders.of(this).get(Something.class);
В Android Studio я не нахожу "android.arch.lifecycle:extensions" для добавления в качестве зависимости. Он говорит "нечего показать", когда я ищу. Я нахожусь на API 27. Итак, пытаясь использовать не устаревшие элементы, я имею это во фрагменте:
public class EventDetailsFragment extends Fragment
{
EventViewModel viewModel;
@Override
public void onActivityCreated (Bundle savedInstanceState)
{
super.onActivityCreated(savedInstanceState);
ViewModelProvider.Factory factory = ViewModelProvider.AndroidViewModelFactory.getInstance(getActivity().getApplication());
// HERE IS THE ISSUE: Seems not good practice to have to create a new ViewModelProvider every time this Fragment is created.
// Perhaps I should just create a singleton ViewModelProvider in the Activity or Application,
// so here could call getActivity().getViewModelProvider(this, factory).
ViewModelProvider viewModelProvider = new ViewModelProvider(this, factory);
viewModel = viewModelProvider.get(EventViewModel.class);
...
}
Что я должен делать?
2 ответа
Открыто app/build.gradle
, Найти dependencies
заблокируйте и добавьте зависимость жизненного цикла вручную в список:
dependencies {
implementation 'android.arch.lifecycle:extensions:1.1.1'
// ...
}
Синхронизируйте проект, и вы сможете впоследствии получить экземпляр ViewModel.
Попробуйте выучить некоторые MVVM
архитектура, если у вас есть лучшее знание Android и Java. Поместите этот код в некоторые baseFragment
метод, а затем сделать:
abstract class BaseFragment extends Fragment() {
//kotlin
fun <T : ViewModel?> getViewModel(activity: FragmentActivity, modelClass: Class<T>): T {
return ViewModelProviders.of(this, ViewModelFactory(activity)).get(modelClass)
}
//bytecode to java is this :/
public final ViewModel obtainViewModel(@NotNull FragmentActivity activity, @NotNull Class modelClass) {
return ViewModelProviders.of((Fragment)this, (Factory)(new
ViewModelFactory((Activity)activity))).get(modelClass);
}
}
также не помещайте этот код в onViewCreated
а не onActivityCreated
// kotlin
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel = obtainViewModel(requireActivity(), KebabFragmentViewModel::class.java)
}
// java bytecode
public void onViewCreated(@NotNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
this.viewModel = (RollerFragmentViewModel)this.obtainViewModel(getFragmentActivity(), RollerFragmentViewModel.class);
}
и теперь вам нужен наблюдатель для чего-то из viewModel место в onViewCreated mby для некоторых, возможно, сетевой операции или что-то, что может занять более длительный период времени
// kotlin
viewModel.list.observe(this, Observer { list ->
list?.let {
viewModel.myKebabAdapter.updateList(list)
}
})
//java
this.viewModel.getErrorMessage().observe((LifecycleOwner)this, (Observer)(new Observer() {
...
public final void onChanged(@Nullable List list) {
this.viewModel.myKebabAdapter.updateKebabList(list)
}
}
и в viewModel вы получили наши прекрасные переменные для наблюдения на activity/fragment
// kotlin
var list: MutableLiveData<MutableList<User>> = MutableLiveData()
// java variable and getter
@NotNull
private MutableLiveData userList;
@NotNull
public final MutableLiveData getUserList() {
return this.userList;
}
Теперь вам нужна зависимость app/build.gradle
в dependencies{}
блок
//lifecycle
implementation "android.arch.lifecycle:extensions:1.1.1"
implementation "android.arch.lifecycle:viewmodel:1.1.1"
// RxJava
implementation "io.reactivex.rxjava2:rxkotlin:2.2.0"
implementation "io.reactivex.rxjava2:rxandroid:2.0.0"
implementation "io.reactivex.rxjava2:rxjava:2.1.10"
Найдите некоторые уроки блога, как правильно это сделать. Мне лично не нравится https://developer.android.com/ которым раньше было трудно следить. Попробуйте Medium.
GL. А Java-код в основном декомпилируется, поэтому надеюсь, что он работает.