Relating to the past question How to get a ViewModel?, and examples I've found, it does not solve my case. I don't have permission to comment there, so I have to ask again. I don't have the ViewModelProviders class which I would like to use the "of" method as in all the examples and documentation I've found, like
model = ViewModelProviders.of(this).get(Something.class);
In Android Studio, I do not find "android.arch.lifecycle:extensions" to add as a dependency. It says "nothing to show" when I search. I am at API 27. So, trying to use the non-deprecated elements, I have this in the Fragment:
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);
...
}
What should I do?
The alternative to a ViewModel is a plain class that holds the data you display in your UI.
To instantiate such basic viewmodel, create a ViewModelProvider with current activity/fragment reference and invoke get method with ViewModel's class.
Open app/build.gradle
, find the dependencies
block and add the lifecycle dependency manually to the list:
dependencies {
implementation 'android.arch.lifecycle:extensions:1.1.1'
// ...
}
Sync the project and you should be able to get an instance of ViewModel afterwards.
Try to learn some MVVM
architecture if u have better knowledge of Android and Java. Put this code into some baseFragment
method and then make:
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);
}
}
also dont put this code into onViewCreated
rather than to 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);
}
and now u need observer for something from viewModel place in onViewCreated mby for some maybe network operation or something what can take longer period of time
// 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)
}
}
and in viewModel u got our lovely variables for observing on 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;
}
Now u need dependency app/build.gradle
in dependencies{}
block
//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"
Find some blog tutorials how to properly do it. I personally dont like https://developer.android.com/ it used to be hard to follow. Try Medium.
GL. And Java code is mostly decompiled so hope it works.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With