首页 > 解决方案 > Firestore 更新后 LiveData 不刷新 RecyclerView

问题描述

我有一个使用 firestore 作为其数据库的 Android 应用程序。我已经按照这一系列博客文章在我的应用程序中设置了我的 firestore 数据库:https ://firebase.googleblog.com/2017/12/using-android-architecture-components.html然后按照这个 stackoverflow 条目更改我的适用于 firestore 的代码:带有 Firebase 的 Android 架构组件,特别是 Firestore

在此之后,我成功地在回收器视图中显示了我的查询结果,但是当我在我的应用程序中添加交换以更新(我通过将 isActive 标志设置为 false 来进行软删除)操作时,LiveData 在刷新 RecyclerView 时不一致. 这是我的代码片段:

MainActivity.java

  TaskViewModel viewModel = 
ViewModelProviders.of(this).get(TaskViewModel.class);

    LiveData<LinkedList<TaskProperties>> liveData = viewModel.getTaskPropertiesLiveData();

    final MainActivity mainActivityReference =  this;

    liveData.observe(this, new Observer<LinkedList<TaskProperties>>() {
        @Override
        public void onChanged(@Nullable LinkedList<TaskProperties> taskProperties) {
            if (taskProperties != null) {

                // Get a handle to the RecyclerView.
                mRecyclerView = findViewById(R.id.recyclerview);
                // Create an adapter and supply the data to be displayed.
                mAdapter = new TaskListAdapter(mainActivityReference, taskProperties);
                // Connect the adapter with the RecyclerView.
                ItemTouchHelper.Callback callback = new SimpleItemTouchHelperCallback(mAdapter);

                ItemTouchHelper touchHelper = new ItemTouchHelper(callback);

                touchHelper.attachToRecyclerView(mRecyclerView);

                mRecyclerView.setAdapter(mAdapter);
                // Give the RecyclerView a default layout manager.
                mRecyclerView.setLayoutManager(new LinearLayoutManager(mainActivityReference));
            }
        }
    });

查看型号:

public class TaskViewModel extends ViewModel {
    private LinkedList<TaskProperties> taskProperties;
    private static final Query PROJECT_REF = FirebaseFirestore.getInstance().collection("project").whereEqualTo("active", true);

    private final FirebaseQueryLiveData liveData = new FirebaseQueryLiveData(PROJECT_REF);

       public TaskViewModel() {
      taskPropertiesLiveData.addSource(liveData, new Observer<QuerySnapshot>() {
            @Override
                public void onChanged(@Nullable final QuerySnapshot querySnapshot) {
                if (querySnapshot != null) {
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            taskProperties =  new LinkedList<TaskProperties>();
                            for (DocumentSnapshot document : querySnapshot.getDocuments()) {
                                taskProperties.addLast(document.toObject(TaskProperties.class));

                            }

                            taskPropertiesLiveData.postValue(taskProperties);
                        }
                    }).start();
                } else {
                    taskPropertiesLiveData.setValue(null);
                }
            }
        });
    }

    @NonNull
    public LiveData<LinkedList<TaskProperties>> getTaskPropertiesLiveData() {
        return taskPropertiesLiveData;
    }
}

要删除的回调类中的代码:

 public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
        mAdapter.onItemDismiss(viewHolder.getAdapterPosition());
    }

适配器中的构造函数:-

  public TaskListAdapter(Context context,LinkedList<TaskProperties> taskList) {
        mInflater = LayoutInflater.from(context);
        this.taskList = taskList;
    }

适配器中要删除的代码:-

  public void onItemDismiss(int position) {

        TaskDao taskDao = new TaskDao();
        taskDao.softDeleteTaskInDB(taskList.get(position));
    }

DAO 类中要更新的代码(软删除):-

public void softDeleteTaskInDB(TaskProperties taskProperties){

    taskProperties.setActive(false);
    database.collection("project")
            .document(taskProperties.getTask())
            .set(taskProperties).
            addOnSuccessListener(new OnSuccessListener<Void>() {
                        @Override
                        public void onSuccess(Void aVoid) {
                            Log.d(DEBUG_TAG, "DocumentSnapshot successfully written!");
                        }
                    })
            .addOnFailureListener(new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception e) {
                    Log.w(DEBUG_TAG, "Error writing document", e);
                }
            });

    Log.i(DEBUG_TAG,taskProperties.getTask());

}

我观察到,当我从列表末尾删除一个组件时,LiveData 能够刷新视图,但是当我从列表中间删除时,视图有时无法正确刷新。从日志中我发现传递给适配器类的位置工作正常,但是任务列表数组没有最新的值。

例如,如果任务列表包含:-

如果连续删除 Mouse 和 Rabbit,则适配器类中的 onItemDismiss 在这两种情况下都会收到位置 3,但 Adapter 类中的 taskList 变量仍然包含位置 3 的 Mouse。这意味着 LiveData 可能没有刷新 RecyclerView。

有人可以告诉我我哪里出错了吗?

谢谢, 桑霍

标签: androidfirebaseandroid-recyclerviewgoogle-cloud-firestore

解决方案


推荐阅读