我正在尝试将MutableLiveData
与数据库中的预填充值一起使用,但是Observer
始终以null
的形式返回book
。我需要将其保留为MutableLiveData
,而不是LiveData
,因为我必须在某些地方以编程方式进行设置。因此,我使用从数据库中检索到的setValue
来调用LiveData
。代码:
ViewModel
:
private final MutableLiveData<Book> bookLiveData;
public MyViewModel(@NonNull Application application) {
super(application);
...
book = new MutableLiveData<>();
bookLiveData.setValue(bookRep.getBookLiveData().getValue());
....
}
Fragment
:
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
...
getActivity().getBookLiveData().observe(getViewLifecycleOwner(), book -> {
... // When fragment is created, book is always null here
});
}
有人可以告诉我为什么观察者中Book
为null吗?我认为Observer
完成并获取值后会通知bookRep.getBookLiveData()
。感谢您的帮助。
答案 0 :(得分:1)
bookRep.getBookLiveData().getValue()
将始终返回null
。由于您要像这样在ViewModel中设置null
值:bookLiveData.setValue(null)
在第7行,bookLiveData
在初始启动时始终为null
。
您不能在getValue()
对象上使用LiveData
在此处获取值,因为在初始化时该值始终为null。您需要观察,以便在它实际发出值时得到通知。
有几种不同的解决方法。一种方法是使用getBookLiveData()
方法在ViewModel中观察observeForever()
。
private LiveData<Book> bookFromRep;
private MutableLiveData<Book> bookLiveData = new MutableLiveData<>();
private Observer<Book> bookObserver = bookLiveData::postValue; // Book observer posts value to bookLiveData.
public MyViewModel(@NonNull Application application) {
super(application);
...
bookFromRep = bookRep.getBookLiveData();
bookFromRep.observeForever(bookObserver);
....
}
@Override
protected void onCleared() {
super.onCleared();
// Don't forget to remove observer when you use observeForever()
bookFromRep.removeObserver(bookObserver);
}
解决这个问题的另一种方法(可能是更好的方法)是使用MediatorLiveData。我将不在这里介绍其实现,但我建议您了解不同的方法并找到适合您需求的最佳方法。