如果我以不同的项目顺序提交相同的列表,则 ListAdapter 不会刷新 RecyclerView

Pri*_*alj 14 android android-recyclerview android-diffutils android-listadapter

我正在使用RecyclerViewwith ListAdapter(它使用AsyncListDiffer在列表被替换时计算和动画更改)。

问题是,如果我submit()列出了一些列表,然后重新排序该列表,submit()同样,什么也没有发生。

ListAdapter即使它“相同”(但顺序已更改),我如何强制评估此新列表?

新发现:

我检查了submitList() 的源代码,并在开始时进行了检查:

public void submitList(@Nullable final List<T> newList) {
        final int runGeneration = ++this.mMaxScheduledGeneration;
        if (newList != this.mList) {
Run Code Online (Sandbox Code Playgroud)

我认为这就是问题所在。但是如何度过呢?我的意思是,开发人员肯定考虑过提交不同的有序列表吗?

Car*_*mer 18

代替

submitList(mySameOldListThatIModified)
Run Code Online (Sandbox Code Playgroud)

您必须提交这样的新列表:

ArrayList newList = new ArrayList(oldList);
newList.add(somethingNew); // Or sort or do whatever you want
submitList(newList);
Run Code Online (Sandbox Code Playgroud)

API有点问题。我们希望 ListAdapter 保留列表的副本,但它没有,可能是出于内存原因。当您更改旧列表时,您实际上是在更改 ListAdapter 存储的相同列表。当 ListAdapter 检查if (newList != this.mList) 两者newListmList引用同一个列表实例时,因此无论您对该列表进行了哪些更改,它都将等于自身,并忽略您的更新。

在 kotlin 中,您可以通过以下方式创建一个新列表:

val newList = oldList.toMutableList() // Unintuitive way to copy a list
newList[0] = newList[0].copy(isFavourite = false) // Do whatever modifications you want
submitList(newList)
Run Code Online (Sandbox Code Playgroud)

请注意,您不能这样做:

newList.first().isFavourite = false
Run Code Online (Sandbox Code Playgroud)

因为这也会更改旧列表中的第一项,并且ListAdapter不会再次看到旧列表中的第一项与新列表中的第一项之间的差异。我建议您列表中的所有项目都val具有专门的属性,以避免出现此问题。

  • 正确的 Kotlin 示例是: `val newList = oldList.toMutableList(); newList[0] = newList.first().copy(isFavourite = false)` (3认同)