【问题标题】:Android Studio: Good practice for handling results from addGeoQueryDataEventListenerAndroid Studio:处理来自 addGeoQueryDataEventListener 的结果的良好做法
【发布时间】:2019-11-30 22:50:02
【问题描述】:

我正在使用 Android 架构组件 (Model-View-ViewModel) 从 GeoFirestoregeoQuery.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);
        }
    }
}

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

感谢您的帮助!

【问题讨论】:

    标签: android mvvm geofirestore


    【解决方案1】:

    您可以设置一个自定义类来包装事件侦听器的数据和状态,并在LiveData 中观察它。您还可以在 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, 
        ....
    }
    

    您可以在 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);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多