LiveData не обновляет RecyclerView после обновления Firestore - PullRequest
0 голосов
/ 25 февраля 2019

У меня есть приложение для Android, которое использует Firestore в качестве своей базы данных.Я следовал за этой серией постов в блоге, чтобы настроить свою базу данных firestore в своем приложении: https://firebase.googleblog.com/2017/12/using-android-architecture-components.html, а затем следовал этой записи stackoverflow, чтобы изменить мой код для работы в firestore: Компоненты архитектуры Android с Firebase, в частности 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 смог обновить представление, когда я удалял один компонент из конца списка, однако при удалении из середины списка представление иногда не обновляется должным образом.Из журналов я обнаружил, что позиция, которая передается в класс адаптера, работает нормально, однако массив списка задач не имеет наиболее обновленного значения.

Например, если список задач содержит: -

  • Кошка
  • Собака
  • Мышь
  • Кролик
  • Tiger

и, если удалить Mouse и затем Rabbit в быстрой последовательности, onItemDismiss в классе адаптера получает позицию 3 в обоих случаях, но переменная taskList в классе Adapter по-прежнему содержит Mouse в позиции 3.Это означает, что LiveData, возможно, не обновил RecyclerView.

Может кто-нибудь сказать мне, где я иду не так?

Спасибо, Сангхо

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...