我的recyclerView
有问题,特别是滚动方面的问题。
我有一个实时更新的列表,其中某些项目被添加、某些项目被删除,并且根据某个参数进行排序。因此,在列表中最初排在第一位的项目可能会更改其参数,在排序后位于不同的位置。
因此,例如,我的recyclerView
专注于最初的项目,但在更改后,当某个项目具有“更好”的参数时,会与该初始项目交换位置。
问题是,在我没有滚动时,我想将焦点放在新项目上,具有“更好”的参数,但我不想在通过触摸滚动时将焦点放在它上面(因此我的触摸不会被滚动到当前列表的第一项所打断)。
因此,我不想在每次更改我的recyclerView
数据后强制执行此代码:
recyclerView.scrollToPosition(0);
因为正如我所说的,当我触摸我的recyclerView
列表并向下滚动查看其他项目时,我会被此滚动打断,同时列表中会发生变化。有没有办法解决这个问题?
具体来说,我正在使用来自DiffUtil的DiffCallback,以支持在当前
recyclerView
列表中发生更改时进行动画处理--它会将旧列表与新列表进行比较,并应用所有需要的动画和通知(添加、删除、更改位置)。所以我从来没有调用过notifyDataSetChanged
这是我的DiffUtil回调:
public static class DevicesDiffCallback extends DiffUtil.Callback{
List<DeviceInfo> oldDevices;
List<DeviceInfo> newDevices;
public DevicesDiffCallback(List<NexoDeviceInfo> newDevices, List<NexoDeviceInfo> oldDevices) {
this.newDevices = newDevices;
this.oldDevices = oldDevices;
}
@Override
public int getOldListSize() {
return oldDevices != null ? oldDevices.size() : 0;
}
@Override
public int getNewListSize() {
return newDevices != null ? newDevices.size() : 0;
}
@Override
public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
return oldDevices.get(oldItemPosition).getNexoIdentifier().getSerialNumber().equals(newDevices.get(newItemPosition).getNexoIdentifier().getSerialNumber());
}
@Override
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
return oldDevices.get(oldItemPosition).equals(newDevices.get(newItemPosition));
}
@Override
public Object getChangePayload(int oldItemPosition, int newItemPosition) {
return super.getChangePayload(oldItemPosition, newItemPosition);
}
}
当我获取新数据列表以替换旧数据时,我会在适配器中像这样设置:
public void setData(List<DeviceInfo> data) {
DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new DevicesDiffCallback(this.mData, data), false);
diffResult.dispatchUpdatesTo(this);
mData = data;
}