我有一个由SortedList支持的RecyclerView适配器。如果我对某个项目进行了更改,它会更改该项目并将其重新定位到列表中。
我发现如果我在项目的起始位置或结束位置使用notifyItemChanged
,那么即使与notifyItemMoved
一起使用,也不会在之前或之后产生任何影响。
如果我使用notifyItemMoved
,它会正确触发移动动画,但视图不会更改,仍会显示过时的信息。
如果我使用notifyDatasetChanged
它会更新行然后移动它,但它按顺序执行,这很慢,并且它显然会通知整个列表,这不是完全合乎需要的。
有什么方法可以结合移动和更新动画吗?为什么notifyItemChanged
没有做任何事情?
答案 0 :(得分:4)
在RecyclerView.Adapter reference中,notifyItemMoved()
只是结构变化,因此不会更新数据。另一方面,据说notifyItemChanged()
是数据更改。
致电notifyItemChanged()
时,会致电RecyclerView#onBindViewHolder()
,因此应该更新您的观点。
我更新和移动的工作方法是:
notifyItemChanged(oldPos); notifyItemMoved(oldPos, newPos);
答案 1 :(得分:0)
看看DiffUtil https://developer.android.com/reference/android/support/v7/util/DiffUtil.html
在适配器中更新数据集后,您可以使用此工具计算正确表示新数据集所需的通知。
扩展DiffUtil.Callback
并实现抽象方法(我创建一个看起来像这样的构造函数:
public MyDiffCallback(ArrayList<String> oldList, ArrayList<String> newList) {
this.oldList = oldList;
this.newList = newList;
}
我在内存中保留oldList
和newList
,以便我可以实现:
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
}
希望这有帮助, GAV
参考:https://medium.com/@iammert/using-diffutil-in-android-recyclerview-bdca8e4fbb00#.yhxirkkq6
答案 2 :(得分:0)
您可以使用:
SortedList.updateItemAt(int position, Objet newItem)
newItem
是更新的项目,position
是当前位置。此方法替换newItem
的当前项,并将其重新定位在列表中(以及它的recyclerview链接)。
Here是官方文档。
我希望这会对你有所帮助。