如何解决为什么列表更改会在整个列表中触发
当 Firestore 数据库中的项目发生变化时,我正在使用带有存储库的 mvp 来更新 recyclerview 上的项目。
如所问,这里有更多来自 SharedModelClass 的代码:
public LiveData<List<Task>> tasksListening() {
return repository.tasksListening(false);
}
导致:
public LiveData<List<Task>> tasksListening(boolean b) {
return new FirestoreTasksData(tasksReference,b);
}
这是 FirestoreTasksData 扩展 LiveData:
public class FirestoreTasksData extends LiveData<List<Task>> {
List<Task> tasks;
for (QueryDocumentSnapshot doc : value) {
Task item = doc.toObject(Task.class);
tasks.add(item);
}
setValue(tasks);
};
}
所有的工作都很完美,只是即使更新了一个项目,列表也会整体更新。
sharedViewModel.tasksListening().observe(getViewLifecycleOwner(),tasks -> {
tasksAdapter.submitList(tasks);
});
这里是适配器代码:
public class MyTasksAdapter extends RecyclerView.Adapter<MyTasksAdapter.TaskHolder> {
private final AsyncListDiffer<Task> mDiffer = new AsyncListDiffer<>(this,DIFF_CALLBACK);
private static final DiffUtil.ItemCallback<Task> DIFF_CALLBACK = new DiffUtil.ItemCallback<Task>() {
@Override
public boolean areItemsTheSame(@NonNull Task oldItem,@NonNull Task newItem) {
return oldItem.getId().equals(newItem.getId());
}
@Override
public boolean areContentsTheSame(@NonNull Task oldItem,@NonNull Task newItem) {
return oldItem.geteDate().equals(newItem.geteDate()) && (new HashSet<>(oldItem.getRoles().values()).equals(new HashSet<>(newItem.getRoles().values())));
}
};
}
public void submitList(List<Task> list) {
mDiffer.submitList(list);
}
@Override
public int getItemCount() {
return mDiffer.getCurrentList().size();
}
这是错误还是功能?我之前用的是 Firestore UI 回收器适配器,刚决定重构代码。
解决方法
这是预期的行为。当查询/集合的结果发生任何更改时,您的代码将被调用,其中包含与查询/集合匹配的所有更改的 QuerySnapshot
object。
如果您想查看发生了什么变化,您可以查看快照的 getDocumentChanges()
以查看这些内容。有关这方面的更多信息(和示例),请参阅 viewing change between snapshots 上的文档。
而不是实现自定义适配器和 DiffUtil 回调。
看看LiveAdapter。
您只需要在 Gradle 中添加最新的依赖项即可。
dependencies {
implementation 'com.github.RaviKoradiya:LiveAdapter:1.3.2-1608532016'
// kapt 'com.android.databinding:compiler:GRADLE_PLUGIN_VERSION' // this line only for Kotlin projects
}
并将适配器与您的 RecyclerView 绑定
LiveAdapter(
data = liveListOfItems,lifecycleOwner = this@MainActivity,variable = BR.item )
.map<Header,ItemHeaderBinding>(R.layout.item_header) {
areContentsTheSame { old: Header,new: Header ->
return@areContentsTheSame old.text == new.text
}
}
.map<Point,ItemPointBinding>(R.layout.item_point) {
areContentsTheSame { old: Point,new: Point ->
return@areContentsTheSame old.id == new.id
}
}
.into(recyclerview)
就是这样。不需要为适配器实现编写额外的代码,观察 LiveData 并通知适配器。
,想删除帖子,但规则。
我解决了这个问题。问题是一切都很好。如果需要,请随意使用代码。
我刚刚意识到内部观察者调用了另一个方法,这就是我看到渲染效果的原因,好像适配器有一些错误。
sharedViewModel.tasksListening().observe(getViewLifecycleOwner(),tasks -> {
tasksAdapter.submitList(tasks);
checkEmpty(tasks.size());
});
private void checkEmpty(int size) {
if (size == 0) {
crossFade(noDataLayout,mTasksRecycler);
} else {
crossFade(mTasksRecycler,noDataLayout);
}
}
我解决了这个问题,现在一切正常。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。