我试图使用MutableLiveData
与数据库预先填充的值,但Observer
总是返回null
作为book
。我需要保持它为MutableLiveData
,而不是LiveData
,因为我必须在某些地方以编程方式设置它。因此,我用从DB检索到的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
在观察者中无效?我认为当Observer
完成并且检索到值时会通知bookRep.getBookLiveData()
。谢谢您的帮助。
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。我不会在此处包含其实现,但我建议理解不同的方法并找到最适合您需求的方法。