I'm using the MVVM architecture. I have an activity and a few fragments, I would like to make a request in the API in the activity, and then using ViewModel, thanks to the obtained data, to display them in the fragment. How should I do this? My current solution that doesn't work:
Activity:
viewModelRoutesFragment = new ViewModelProvider(this).get(ViewModelRoutesFragment.class);
viewModelRoutesFragment.init();
Fragment:
viewModelRoutesFragment = new ViewModelProvider(this).get(ViewModelRoutesFragment.class);
viewModelRoutesFragment.getRoutes().observe(getActivity(), new Observer<List<RoutesResponse>>() {
@Override
public void onChanged(List<RoutesResponse> routes) {
//Show data
}
});
Repository:
public class RemoteRepository {
private ApiRequest apiRequest;
private MutableLiveData<List<RoutesResponse>> routes = new MutableLiveData<>();
public RemoteRepository() {
apiRequest = RetrofitRequest.getInstance().create(ApiRequest.class);
}
public MutableLiveData<List<RoutesResponse>> getRoutes() {
apiRequest.getRoutes()
.enqueue(new Callback<List<RoutesResponse>>() {
@Override
public void onResponse(Call<List<RoutesResponse>> call, Response<List<RoutesResponse>> response) {
if (response.isSuccessful())
routes.setValue(response.body());
}
@Override
public void onFailure(Call<List<RoutesResponse>> call, Throwable t) {
Log.i("Failure", "Fail!");
}
});
return routes;
}
}
ViewModel:
public class ViewModelRoutesFragment extends AndroidViewModel {
private RemoteRepository remoteRepository;
private LiveData<List<RoutesResponse>> routes;
public ViewModelRoutesFragment(@NonNull Application application) {
super(application);
}
public void init() {
remoteRepository = new RemoteRepository();
routes = remoteRepository.getRoutes();
}
public LiveData<List<RoutesResponse>> getRoutes() {
return routes;
}
}
Currently getting a null error. How can I avoid it properly?
java.lang.NullPointerException: Attempt to invoke virtual method 'void androidx.lifecycle.LiveData.observe(androidx.lifecycle.LifecycleOwner, androidx.lifecycle.Observer)' on a null object reference
Use activity's scope to create an instance of the ViewModel in fragment so that all the fragments and activity now has a common ViewModel and have access to the same ViewModelStore . If the activity is re-created, it and all its fragments receive the same ViewModel instance that was created by the associated activity.
In android, we can use ViewModel to share data between various fragments or activities by sharing the same ViewModel among all the fragments and they can access everything defined in the ViewModel. This is one way to have communication between fragments or activities.
You should have an instance of fragments inside the activity. Your fragment already holding a reference to the ViewModel. Delete these line from the activity -> : viewModelRoutesFragment = new ViewModelProvider(this).
Basically, we are trying to share the viewmodel across the activity and fragment. so while during the activity creation we have to create the instance of viewmodel
viewModelRoutesFragment = new ViewModelProvider(requireActivity()).get(ViewModelRoutesFragment.class);
viewModelRoutesFragment.init();
In fragment also we need to reuse the ViewModelRoutesFragment so in onViewCreated() get the instance of the ViewModel and observe the live data
viewModelRoutesFragment = new ViewModelProvider(requireActivity()).get(ViewModelRoutesFragment.class);
viewModelRoutesFragment.getRoutes().observe(getActivity(), new Observer<List<RoutesResponse>>() {
@Override
public void onChanged(List<RoutesResponse> routes) {
// updation of UI
}
});
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