У меня есть приложение для 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.
Может кто-нибудь сказать мне, где я иду не так?
Спасибо, Сангхо