我正在使用Android体系结构组件( Model-View-ViewModel )从 GeoFirestore
获取geoQuery.addGeoQueryDataEventListener()
的结果
实现'com.github.imperiumlabs:GeoFirestore-Android:v1.5.0'
每个事件都有自己的回调,而我对所有事件都感兴趣。
我还使用BottomNavigationView
,这意味着我只有一个活动,而我所有的逻辑都放在片段中。
我首先实现了onDocumentEntered()
,如下所示,我意识到,当我导航到下一个活动并返回到调用 MVVM 的上一个活动时,recyclerView会瞬间复制数据。
public class FirestoreGeoQuery extends LiveData<List<StoreModel>> {
private static final String TAG = "debinf FBGeoQuery";
private GeoQuery geoQuery;
private Class clazz;
private List<StoreModel> itemList = new ArrayList<>();
public FirestoreGeoQuery(GeoQuery geoQuery, Class clazz) {
this.geoQuery = geoQuery;
this.clazz = clazz;
}
GeoQueryDataEventListener geoQueryDataEventListener = new GeoQueryDataEventListener() {
@Override
public void onDocumentEntered(@NotNull DocumentSnapshot documentSnapshot, @NotNull GeoPoint geoPoint) {
Log.i(TAG, "onDocumentEntered: "+documentSnapshot);
if (documentSnapshot.exists()) {
StoreModel item = (StoreModel) documentSnapshot.toObject(clazz);
item.setGeoPoint(geoPoint);
Log.i(TAG, "onDocumentEntered: addGeoQueryDataEventListener - store.name: "+item.getName()+", address: "+item.getAddress()+", geoPoint: "+item.getGeoPoint());
itemList.add(item);
}
}
@Override
public void onDocumentExited(@NotNull DocumentSnapshot documentSnapshot) {
Log.i(TAG, "onDocumentExited: ");
}
@Override
public void onDocumentMoved(@NotNull DocumentSnapshot documentSnapshot, @NotNull GeoPoint geoPoint) {
Log.i(TAG, "onDocumentMoved: ");
}
@Override
public void onDocumentChanged(@NotNull DocumentSnapshot documentSnapshot, @NotNull GeoPoint geoPoint) {
Log.i(TAG, "onDocumentChanged: ");
}
@Override
public void onGeoQueryReady() {
Log.i(TAG, "onGeoQueryReady: ");
setValue(itemList);
}
@Override
public void onGeoQueryError(@NotNull Exception e) {
Log.i(TAG, "onGeoQueryError: ");
}
};
@Override
protected void onActive() {
super.onActive();
geoQuery.addGeoQueryDataEventListener(geoQueryDataEventListener);
}
@Override
protected void onInactive() {
super.onInactive();
if (!hasActiveObservers()) {
geoQuery.removeGeoQueryEventListener(geoQueryDataEventListener);
}
}
}
所以我的问题是:如何正确处理每个事件回调的结果?
感谢您的帮助!
答案 0 :(得分:0)
您可以设置一个自定义类来包装数据和事件侦听器的状态,并在LiveData
中进行观察。您还可以在ViewModel
本身中处理侦听器,以便仅将其添加一次,并在清除ViewModel
后将其清除。如果您希望在ViewModel
的整个生命周期中保持数据持久,则将数据存储在Activity
中也是个好主意。
ViewModel
private MutableLiveData<Resource<StoreModel>> data;
private Resource resource;
private List<StoreModel> itemList = new ArrayList<>();
public MyViewModel() {
resource = new Resource();
data = getData();
GeoQueryDataEventListener geoQueryDataEventListener = new GeoQueryDataEventListener() {
@Override
public void onDocumentEntered(@NotNull DocumentSnapshot documentSnapshot, @NotNull GeoPoint geoPoint) {
Log.i(TAG, "onDocumentEntered: "+documentSnapshot);
if (documentSnapshot.exists()) {
StoreModel item = (StoreModel) documentSnapshot.toObject(clazz);
item.setGeoPoint(geoPoint);
data.postValue(resource.onDocumentEntered(item));
}
}
@Override
public void onDocumentExited(@NotNull DocumentSnapshot documentSnapshot) {
Log.i(TAG, "onDocumentExited: ");
data.postValue(resource.onDocumentExited(...));
}
@Override
public void onDocumentMoved(@NotNull DocumentSnapshot documentSnapshot, @NotNull GeoPoint geoPoint) {
Log.i(TAG, "onDocumentMoved: ");
data.postValue(resource.onDocumentMoved(...));
}
@Override
public void onDocumentChanged(@NotNull DocumentSnapshot documentSnapshot, @NotNull GeoPoint geoPoint) {
Log.i(TAG, "onDocumentChanged: ");
data.postValue(resource.onDocumentChanged(...));
}
@Override
public void onGeoQueryReady() {
Log.i(TAG, "onGeoQueryReady: ");
data.postValue(resource.onGeoQueryReady(...));
}
@Override
public void onGeoQueryError(@NotNull Exception e) {
Log.i(TAG, "onGeoQueryError: ");
data.postValue(resource.onGeoQueryError(...));
}
geoQuery.addGeoQueryDataEventListener(geoQueryDataEventListener);
}
@Override
protected void onCleared() {
geoQuery.removeGeoQueryEventListener(geoQueryDataEventListener);
}
public MutableLiveData<Resource<StoreModel>> getData() {
if (data == null) {
data = new MutableLiveData<Resource<StoreModel>>();
}
return data;
}
资源
class Resource {
private Status currentStatus;
private StoreModel item;
public Resource() { }
public Resource onDocumentEntered(StoreModel item) {
this.status = Status.ON_DOCUMENT_ENTERED;
this.item = item;
return this;
}
.... handle other functions
}
状态
enum Status {
ON_DOCUMENT_ENTERED,
ON_DOCUMENT_EXITED,
....
}
您可以按照以下步骤在您的片段中初始化并观察它:
@Override
protected void onStart() {
// initialize existing data
if (viewModel.getItemList().size() > 0) {
updateUI(data);
}
// observe listener events
observer = new Observer<Resource<List<String>>>() {
@Override
public void onChanged(@Nullable final Resource<List<String>> resource) {
switch(resource.getCurrentStatus()) {
case Status.ON_DOCUMENT_ENTERED:
viewModel.getItemList().add(resource.getItem());
....
break;
case Status.ON_DOCUMENT_EXITED:
...
break;
...
}
}
};
viewModel.getData().observe(this, observer);
}
@Override
protected void onStop() {
viewModel.getData().removeObserver(observer);
}