mik*_*oxy 8 java android mvvm android-fragments android-livedata
我正在使用 MVVM 架构。我有一个activity和几个fragment,我想在activity中的API中做一个请求,然后使用ViewModel,得益于获取到的数据,将它们展示在fragment中。我该怎么做?我目前的解决方案不起作用:
活动:
viewModelRoutesFragment = new ViewModelProvider(this).get(ViewModelRoutesFragment.class);
viewModelRoutesFragment.init();
Run Code Online (Sandbox Code Playgroud)
分段:
viewModelRoutesFragment = new ViewModelProvider(this).get(ViewModelRoutesFragment.class);
viewModelRoutesFragment.getRoutes().observe(getActivity(), new Observer<List<RoutesResponse>>() {
@Override
public void onChanged(List<RoutesResponse> routes) {
//Show data
}
});
Run Code Online (Sandbox Code Playgroud)
存储库:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
视图模型:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
当前收到空错误。我怎样才能正确避免它?
java.lang.NullPointerException: Attempt to invoke virtual method 'void androidx.lifecycle.LiveData.observe(androidx.lifecycle.LifecycleOwner, androidx.lifecycle.Observer)' on a null object reference
Run Code Online (Sandbox Code Playgroud)
小智 11
在片段使用中
viewModelRoutesFragment = new ViewModelProvider(requireActivity()).get(ViewModelRoutesFragment.class);
Run Code Online (Sandbox Code Playgroud)
代替
viewModelRoutesFragment = new ViewModelProvider(this).get(ViewModelRoutesFragment.class);
Run Code Online (Sandbox Code Playgroud)
小智 6
基本上,我们试图在活动和片段之间共享视图模型。所以在活动创建期间我们必须创建视图模型的实例
viewModelRoutesFragment = new ViewModelProvider(requireActivity()).get(ViewModelRoutesFragment.class);
viewModelRoutesFragment.init();
Run Code Online (Sandbox Code Playgroud)
在片段中,我们还需要重用 ViewModelRoutesFragment,因此在 onViewCreated() 中获取 ViewModel 的实例并观察实时数据
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
}
});
Run Code Online (Sandbox Code Playgroud)
您不需要在活动中引用视图模型。您应该在活动中拥有一个片段实例。您的片段已经包含对 ViewModel 的引用。从 Activity -> 中删除这些行:
viewModelRoutesFragment = new ViewModelProvider(this).get(ViewModelRoutesFragment.class);
viewModelRoutesFragment.init();
Run Code Online (Sandbox Code Playgroud)
确保在活动中初始化片段。您的活动只是一个持有者块,它实际上使用片段管理器替换片段。如果您使用片段,它不需要任何视图模型。
viewModelRoutesFragment.init();
另外,在该行下方的片段中调用此方法
viewModelRoutesFragment = new ViewModelProvider(this).get(ViewModelRoutesFragment.class);
Run Code Online (Sandbox Code Playgroud)