RecyclerView - 如何同时更新和移动项目

问题描述 投票:8回答:3

我有一个由SortedList支持的RecyclerView适配器。如果我对某个项目进行了更改,它将更改该项目并将其重新定位到列表中。

我发现,如果我在项目的起始位置或结束位置使用notifyItemChanged,那么即使与notifyItemMoved一起使用也不会产生任何影响,无论是在之前还是之后。

如果我使用notifyItemMoved,它会正确触发移动动画,但视图不会更改,仍会显示过时的信息。

如果我使用notifyDatasetChanged它更新行然后移动它,但它按顺序这样做很慢,它显然通知整个列表,这是不完全合乎需要的。

有什么方法可以结合移动和更新动画吗?为什么notifyItemChanged什么都不做?

android android-recyclerview sortedlist
3个回答
4
投票

RecyclerView.Adapter reference说,notifyItemMoved()只是结构变化,因此不会更新数据。另一方面,据说notifyItemChanged()是数据变化。

当调用notifyItemChanged()时,它会调用RecyclerView#onBindViewHolder(),因此它应该更新你的视图。

我更新和移动的工作方法是:

notifyItemChanged(oldPos); notifyItemMoved(oldPos, newPos);


0
投票

看看DiffUtil https://developer.android.com/reference/android/support/v7/util/DiffUtil.html

在适配器中更新数据集后,可以使用此工具计算正确表示新数据集所需的通知。

  1. 扩展DiffUtil.Callback并实现Abstract方法(我创建一个看起来像这样的构造函数: public MyDiffCallback(ArrayList<String> oldList, ArrayList<String> newList) { this.oldList = oldList; this.newList = newList; }

我在内存中持有oldListnewList,以便我可以实现:

areItemsTheSame areContentsTheSame getNewListSize getOldListSize

例如:

@Override
public int getOldListSize() {
    return oldList.size();
}
@Override
public int getNewListSize() {
    return newList.size();
}
@Override
public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
    return oldList.get(oldItemPosition).equals(newList(newItemPosition))
}
@Override
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
    return areItemsTheSame(oldItemPosition, newItemPosition);
}

areItemsTheSame:告诉UTIL项目是否已移动(检查位置)areContentsTheSame:通知UTIL项目内容是否已更改。

现在你在updateDataSet方法中(或者你所谓的任何方法!);做类似的事情:

public updateDataSet(List newDataSet) {
    // this.dataSet is the old data set / List
    final MyDiffCallback callback = new MyDiffCallback(this.dataSet, newDataSet);
    final DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(callback);

    this.dataSet = newDataSet;
    diffResult.dispatchUpdatesTo(this); //This is the Adapter
}

希望这有帮助,加夫

参考:https://medium.com/@iammert/using-diffutil-in-android-recyclerview-bdca8e4fbb00#.yhxirkkq6


0
投票

您可以使用:

SortedList.updateItemAt(int position, Objet newItem)

newItem是更新的项目,position是当前位置。此方法替换newItem的当前项目并将其重新定位在列表上(以及它的recyclerview链接)。

Here是官方文件。

我希望这可以帮助你。

© www.soinside.com 2019 - 2024. All rights reserved.