0

我正在使用 Android 架构组件(Model-View-ViewModelgeoQuery.addGeoQueryDataEventListener()GeoFirestore获取结果

实施 '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);
        }
    }
}

所以我的问题是:如何正确处理每个事件回调的结果?

我很感激任何帮助!

4

1 回答 1

0

您可以设置一个自定义类来包装事件侦听器的数据和状态,并在LiveData. 您还可以自己处理侦听器ViewModel,使其仅添加一次,并在清除后ViewModel清除。ViewModel如果您希望数据在Activity.

视图模型

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, 
    ....
}

您可以在Fragment中初始化并观察它,如下所示:

@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);
}
于 2020-01-11T23:38:09.793 回答