当我向ListAdapter提交数据时遇到问题,它没有显示所有数据。
查看模型概念
因此,在我的视图模型中,我从 firebase 获取数据来显示它。这是我的处理方法,有一个名为 getAllStudents() 的函数,它对 firestore 中的 Collection 引用进行 get() ,返回的数据是 ids,因此我创建了另一个函数来获取 ids 的实际数据。但我认为问题是,每次当我获取第一次调用返回的任何 id 的数据时,我都会将数据发布到 liveData,因此数据不完整,这会使 ListAdatper 提交此数据,但是 然而它在最后起作用,但有些项目与所有数据一起显示,而其他项目则没有。 导致此行为:https://fastupload.io/xOb6Ara7S81WpIW/preview
viewModel 函数示例 例如我有 4 个函数,当它检索数据时,它会调用 LiveData 上的 postValue()
示例
@Override
public void onSuccess(QuerySnapshot querySnapshot) {
_uiState.postValue(false);
for (DocumentSnapshot item:querySnapshot){
Student studentItem = item.toObject(Student.class);
if (studentItem.id.equals(student.id)){
for (StudentDetails studentDetails:studentsDetailsList){
if (studentDetails.studentId.equals(student.id)){
studentDetails.student = studentItem;
_studentsDetails.postValue(studentsDetailsList);
}
}
}
}
}
然后每次任何函数调用 success 时,ListAdatper 都会使用未完成的数据或已完成的数据调用 SubmitList (当数据完成时,适配器不会更新所有项目)
这是附加到 liveData 的观察者
viewModel.studentsDetails.observe(getViewLifecycleOwner(), new Observer<List<StudentDetails>>() {
@Override
public void onChanged(List<StudentDetails> students) {
// Submitting the list to the recycler view adapter
studentsAdapter.submitList(students);
Log.e("observed", students.toString());
if (students.isEmpty()){
binding.containerNoData.setVisibility(VISIBLE);
}else{
binding.containerNoData.setVisibility(View.INVISIBLE);
}
}
});
以及列表Adapter的diffutil
new DiffUtil.ItemCallback<StudentDetails>() {
@Override
public boolean areItemsTheSame(@NonNull StudentDetails oldItem, @NonNull StudentDetails newItem) {
return oldItem.id.equals(newItem.id);
}
@Override
public boolean areContentsTheSame(@NonNull StudentDetails oldItem, @NonNull StudentDetails newItem) {
return newItem.equals(oldItem) && newItem.toString().equals(oldItem.toString());
}
});
注意: 当我记录观察到的数据时,它是正确的
这是由于
submitList()
方法的底层实现造成的。如果您提供相同的列表,即使列表中的项目发生更改,它也不会执行任何检查。
DiffUtils 的
submitList()
将提交的列表与之前的列表进行比较,如果您再次提供相同的列表,它会将它们视为相同,而不考虑列表项本身的任何更改。
这是一种奇怪的行为,我过去也浪费了很长时间来调试这个问题。解决方案是每次将一个新列表传递给
submitList()
。
studentsAdapter.submitList(new ArrayList<Student>(students));