我在notifyDataSetChanged
中使用了recycleriew
。像这样:
private void setList(List<Article> articles) {
mainList.addAll(articles);
notifyDataSetChanged();
}
但是我想在diffUtill
中使用recycleriew
。我这样创建了自己的diffUtill
:
public class ArticleListDiffTool extends DiffUtil.Callback {
List<Article> oldList;
List<Article> newList;
private static final String TAG = "ArticleListDiffTool";
public ArticleListDiffTool(List<Article> oldList, List<Article> newList) {
this.oldList = oldList;
this.newList = newList;
Log.d(TAG, "ArticleListDiffTool: " + this.oldList.size() + "\n" + this.newList.size());
}
@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).getId() .equals( newList.get(newItemPosition).getId());
}
@Override
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
return oldList.get(oldItemPosition).equals(newList.get(newItemPosition));
}
@Nullable
@Override
public Object getChangePayload(int oldItemPosition, int newItemPosition) {
//you can return particular field for changed item.
return super.getChangePayload(oldItemPosition, newItemPosition);
}
}
然后在适配器中使用它:
private void setList(列表文章){
DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new ArticleListDiffTool(this.mainList, articles),true);
mainList.addAll(articles);
diffResult.dispatchUpdatesTo(this);
}
我想将新数据添加到我的旧列表中。但是,当收到新数据时,recyclerView
将滚动到列表顶部。
但是我希望recyclerView处于用户状态,并将新数据添加到旧列表的其余部分。
答案 0 :(得分:1)
如果您在recyclerview的末尾添加新项目,则在添加数据之前,将第一个可见项目存储在recyclerview中:
int position = ((LinearLayoutManager) recyclerView.GetLayoutManager()).findFirstVisibleItemPosition();
,然后进行所有更改并调用notifyDatasetChanged()
,滚动到position
:
recyclerView.scrollToPosition(position);
答案 1 :(得分:1)
RecylcerView更新对您的视图一无所知。当您调用notifyDataSetChanged
时,它将尝试确定哪些视图已移动或已替换。我看不到您使用setHasStableIds
,因此在调用notifyDataSetChanged
时它将假定所有内容均已替换。它将跳到位置0
并完成操作。使用setHasStableIds
时,它将检查可见项目的ID并更新其中的内容。它将停止跳来跳去。
现在,您还表明您正在使用DiffUtil
。这很棒!当您不使用setHasStableIds
时,这是正确告知recyclerView有关更改的方法。
您面临的问题是同时使用两者。要么移动到long
id,然后让recyclerview自己进行比较,要么使用DiffUtil并删除对notifyDataSetChanged
的调用。两种变体都应该起作用。
答案 2 :(得分:0)
几个小时后我发现了问题。
我每次想要更新recyclerView时都将接收到的数据发送到我的适配器 然后DiffUtil会将我的旧列表与收到的新零件进行比较,因此(完全是新商品),DiffUtil决定刷新整个recyclerView列表。
解决方案:
现在,我从recyclerView
适配器获取当前列表,并使用addAll
插入从服务器接收到的新项目,然后将此完整列表传递给适配器。
现在DiffUtil可以比较新旧列表之间的区别,并且recyclerView将保持在当前位置。