[我不熟悉LiveData
和ViewModels
,并且我不完全了解如何更新数据。
而不是每次应用程序数据更改时都更新UI,每次更改时,观察者都可以更新UI。
这句话对我来说毫无意义。我正在使用Sqlite数据库(没有Room),并且正在getItems()
的ViewModel
方法中异步获取数据。这是否意味着在数据库中添加或更新数据时,LiveData
将自动检测到它并调用onChange
?
据Android开发者网站称,它开始观察LiveData
中的onCreate
对象。在使用LiveData
之前,我通过查询数据库然后调用onResume
来刷新notifyDataSetChanged()
中的数据。
此代码现在在加载Fragment
时显示数据,但是如果我删除数据库或向数据库添加新数据,则UI不会反映更改。我只是认为我对LiveData
的工作方式没有基本的了解,在任何地方都找不到很好的解释。
[帮助我StackOverflow,您是我唯一的希望。
public class MyViewModel extends AndroidViewModel {
private MutableLiveData<List<String>> items;
private Application application;
public MyViewModel(@NonNull Application application) {
super(application);
this.application = application;
}
public MutableLiveData<List<String>> getItems() {
if (items == null) {
items = new MutableLiveData<>();
getItems();
}
return items;
}
private void getItems() {
List<String> items = GetItems(); //async process
this.items.setValue(items)
}
}
public class ListFragment extends Fragment {
@Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MyViewModel model = ViewModelProviders.of(getActivity()).get(MyViewModel.class);
final Observer<List<String>> observer = new Observer<List<String>>() {
@Override
public void onChanged(List<String> items) {
//update UI
}
};
model.getItems().observe(this, observer);
}
}
您的代码似乎正确。您正在正确设置所有内容,并且每次Observer
值更改时,都会在ListFragment
中的LiveData
上收到回调。
但是,使用该代码,LiveData的值将永远不会改变,因此您的LiveData的Observer将仅被调用一次。您仅在MyViewModel.getItems
中调用一次onCreate
。此方法还将执行两件事:返回LiveData并获取项目列表。
第一种方法是将ViewModel getItems
方法分为两种:一种用于获取LiveData,另一种用于刷新实际的项目列表。在片段中,您将像往常一样在onResume()
中刷新数据。
看起来像这样:
public class MyViewModel extends ViewModel {
private final MutableLiveData<List<String>> items = new MutableLiveData<>();
public LiveData<List<String>> getItemsLiveData() {
return items;
}
public void refreshItems() {
List<String> items = GetItems(); //async process
this.items.setValue(items)
}
}
public class ListFragment extends Fragment {
private MyViewModel model;
@Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
model = ViewModelProviders.of(getActivity()).get(MyViewModel.class);
final Observer<List<String>> observer = new Observer<List<String>>() {
@Override
public void onChanged(List<String> items) {
//update UI
}
};
model.getItemsLiveData().observe(this, observer);
}
@Override
public void onResume() {
model.refreshItems()
}
}
要走得更远,您将需要更改实际刷新项目的方式。如果要在修改数据库时在ViewModel中收到通知,则还需要在ViewModel与数据库之间的通信中使用Observer模式(带有LiveData的房间,RxJava的Observable或新的协程Flow是开始的好地方)] >
这里是使用RxJava的伪算法示例:
public class MyViewModel extends ViewModel { private final MutableLiveData<List<String>> items = new MutableLiveData<>(); public MyViewModel() { myDatabase.getDatabaseObservable() .subscribe(new Subscriber<List<String>>() { @Override public void onCompleted() { } @Override public void onNext(List<String> newItems) { items.setValue(newItems) } @Override public void onError() { } }) } public LiveData<List<String>> getItemsLiveData() { return items; } }
其中的最后一部分将在您的数据库类中创建该Observable(可以使用像Room一样自动运行的Library或通过创建自己的
PublishSubject
来创建。)>