Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/191.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 为什么列表更改会触发整个列表_Android_Google Cloud Firestore_Android Livedata - Fatal编程技术网

Android 为什么列表更改会触发整个列表

Android 为什么列表更改会触发整个列表,android,google-cloud-firestore,android-livedata,Android,Google Cloud Firestore,Android Livedata,当firestore数据库中的项目发生变化时,我正在使用mvp with repository更新recyclerview上的项目 如前所述,以下是来自SharedModelClass的更多代码: public LiveData<List<Task>> tasksListening() { return repository.tasksListening(false); } 下面是适配器代码: public class MyTask

当firestore数据库中的项目发生变化时,我正在使用mvp with repository更新recyclerview上的项目

如前所述,以下是来自SharedModelClass的更多代码:

   public LiveData<List<Task>> tasksListening() {
        return repository.tasksListening(false);
    }
下面是适配器代码:

    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();
    }
公共类MyTasksAdapter扩展了RecyclerView.Adapter{
private final AsyncListDiffer mDiffer=新的AsyncListDiffer(这是DIFF_回调);
私有静态final DiffUtil.ItemCallback DIFF_CALLBACK=new DiffUtil.ItemCallback(){
@凌驾
公共布尔值AreItemsSame(@NonNull任务oldItem,@NonNull任务newItem){
返回oldItem.getId().equals(newItem.getId());
}
@凌驾
公共布尔值是相同的内容(@NonNull Task oldItem、@NonNull Task newItem){
返回oldItem.geteDate().equals(newItem.geteDate())&&(新哈希集(oldItem.getRoles().values()).equals(新哈希集(newItem.getRoles().values()));
}
};
}
公共无效提交列表(列表){
mDiffer.提交列表(列表);
}
@凌驾
public int getItemCount(){
返回mDiffer.getCurrentList().size();
}

这是一个bug还是一个特性?我以前使用Firestore UI回收器适配器,只是决定重构代码。

这是预期行为。当查询/集合的结果发生任何更改时,您的代码将被调用,其中包含与查询/集合匹配的所有更改


如果要查看发生了哪些更改,可以查看快照的
getDocumentChanges()
,查看这些更改。有关这方面的更多信息(以及示例),请参阅。

上的文档,而不是实现自定义适配器和DiffUtil回调

看一看

您只需要在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)
LiveAdapter(
数据=liveListOfItems,
生命周期所有者=this@MainActivity,
变量=BR.item)
.地图(右布局.项目标题){
内容是否相同{old:Header,new:Header->
return@areContentsTheSameold.text==new.text
}
}
.地图(右布局图项目\ U点){
内容是否相同{旧:点,新:点->
return@areContentsTheSameold.id==new.id
}
}
.进入(回收视图)

就这样。无需为适配器实现编写额外代码,请观察LiveData并通知适配器。

希望删除post,但不删除规则

我解决了这个问题。问题是,所有的工作都很好。如果需要,可以随意使用代码

我刚刚意识到,inside observer调用了另一个方法,这就是我看到渲染效果的原因,就好像适配器存在一些bug一样

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);

        }
    }

我解决了这个问题,现在一切正常。

FirestoreTasksData的代码看起来不完整,因为没有构造函数或方法。还不清楚您是如何使用它的,或者Firestore查询来自何处。请编辑该问题以显示重现该问题的。已使用一些代码更新。你在这方面有什么进展吗?下面有三个人试图帮助你。你有机会检查他们的答案吗?如果答案有用,请单击向上投票按钮(▲) 如果它回答了您的问题,请单击复选标记(✓) 接受它。这样其他人就知道你得到了(足够)的帮助。另请参见LiveData只有一个方法setValue。如果项发生更改,我应该只将这些项添加到列表中并传递它。这不起作用。以前添加的项将被删除。您可以通过查看
getDocumentChanges()来确定添加了什么
如我链接的文档所示。但您也可以简单地清除现有列表,然后使用此处显示的代码重新填充其中一个:
dependencies {
    implementation 'com.github.RaviKoradiya:LiveAdapter:1.3.2-1608532016'
    // kapt 'com.android.databinding:compiler:GRADLE_PLUGIN_VERSION' // this line only for Kotlin projects
}
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)
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);

        }
    }