每次用户来到HomeFragment
时,我需要执行一项任务。不管是新创建的还是用户回到此Fragment
。
在新创建时可以正常工作,但是从后退堆栈返回时,不会调用观察器。我使用调试器发现的是LiveData
有观察者,但hasActiveObservers()
返回false 。我尝试从不同的生命周期回调中操作和观察/删除Observer,但均未成功。在Google中也找不到清晰的解释。
这是我的HomeFragment.java
:
public class HomeFragment extends BaseFragment {
//.......
private ImportViewModel viewModel;
private Observer<State> observer = state -> {
//update UI depending on a state
};
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
viewModel = ViewModelProviders.of(this, viewModelFactory).get(ImportViewModel.class);
observeViewModel();
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_home, container, false);
//execute here since onCreate() is not called when coming from backstack
viewModel.importFile();
return v;
}
@Override
public void onDestroy() {
super.onDestroy();
viewModel.liveDataState.removeObserver(observer);
}
private void observeViewModel() {
viewModel.liveDataState.observe(this, observer);
}
//.......
}
还有ImportViewModel.java
public class ImportViewModel extends ViewModel {
//......
public MutableLiveData<State> liveDataState = new MutableLiveData<>();
//......
public void importFile(){
disposables.add(repository.importFile()
.subscribeOn(subscribeOnScheduler)
.observeOn(observeOnScheduler)
.subscribe(this::onNext, this::onError, this::onComplete));
}
private void onNext(SomeResponse resp){
liveDataState.setValue(new State(resp));
}
private void onError(Throwable t){
liveDataState.setValue(new ErrorState(t.getMessage()));
}
private void onComplete(){
liveDataState.setValue(new CompleteState());
}
}
为什么观察者不活动?
答案 0 :(得分:0)
我有类似的问题。我的情况是我要从家庭片段转到另一个片段,并且通过将片段视图设置为全局来维护片段的状态,在create view方法中,我首先检查视图是否不为null,然后不进行任何设置。到那时为止一切都很好。
我的问题是,当我从那个片段回来时,实时数据的变化没有被观察到。
我设法用onResume方法做到这一点。
private fun setupObserver() {
val observer: Observer<MutableList<Post>> = Observer {
// textView.text = homeViewModel.text.value?.get(0)?.name ?: "Loading"
Log.d(
AppConstants.GLOBAL_LOGTAG,
"observed with current page = ${homeViewModel.getMetaData().currentPage}"
)
//logic to show progress
if (!isObservedAtLeastOneTime) {
showProgress()
}
if (homeViewModel.getMetaData().currentPage == 1) {
list.clear()
list.addAll(homeViewModel.mutableLiveData.value!!)
recentPostsAdapter.notifyDataSetChanged()
} else {
list.clear()
list.addAll(homeViewModel.mutableLiveData.value!!)
recentPostsAdapter.notifyDataSetChanged()
}
if (isObservedAtLeastOneTime) {
hideProgressAndShowContent()
}
isObservedAtLeastOneTime = true
isLoading = false
swipeRefreshLayout.isRefreshing = false
}
if (!homeViewModel.mutableLiveData.hasActiveObservers()) {
homeViewModel.mutableLiveData.observe(viewLifecycleOwner, observer)
}
}
然后使用恢复方法。
override fun onResume() {
super.onResume()
if(!homeViewModel.mutableLiveData.hasActiveObservers()){
setupObserver()
}
}