RecyclerView 使用 DiffUtil,防止在更改时滚动底部

K.O*_*.Os 10 android android-recyclerview

我的recyclerViev,特别是滚动有问题。我有一些列表,它是实时更新的,添加了一些项目,删除了一些项目,并且所有内容都按某个参数排序。因此,最初在列表中的第一个项目,可以更改其参数,排序后将处于不同的位置。

因此recyclerView,例如,我专注于初始项目,并且在更改之后,当某些项目具有“更好”的参数时,会更改该初始项目的位置。

问题是,我想专注于新项目,当我不滚动时使用“更好”的参数,但是当我通过触摸滚动时我不想专注于它(所以我的触摸不会被滚动到当前列表中的第一项)。

所以我不想在每次更改recyclerView数据后强制执行此代码:

recyclerView.scrollToPosition(0);
Run Code Online (Sandbox Code Playgroud)

因为正如我所说,当我触摸我的recyclerView列表并向下查看其他项目时,我会被这个卷轴打断,同时我的列表也会发生变化。

有没有办法做到这一点?

具体来说,我正在使用DiffUtilDiffCallback,以在我当前的 recyclerView 列表发生变化时支持动画 - 它将旧列表与另一个新列表进行比较并应用所有想要的动画和通知(添加、删除、更改项目位置)。所以我从不打电话

notifyDataSetChanged
Run Code Online (Sandbox Code Playgroud)

或类似的东西

这是我的 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

当我获取要填充的新数据列表并替换旧数据时,我在适配器中将其设置为这样:

 public void setData(List<DeviceInfo> data) {
    DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new DevicesDiffCallback(this.mData, data), false);
    diffResult.dispatchUpdatesTo(this);

        mData = data;

}
Run Code Online (Sandbox Code Playgroud)

Vic*_*cky 2

我不确定这个答案,但是我认为您的调用代码DiffUtil不正确。尝试使用这个:

public void addItems(List<Recipe> recipeList) {

    List<Recipe> newRecipeList = new ArrayList<>();
    newRecipeList.addAll(this.recipeList);
    newRecipeList.addAll(recipeList);

    DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new RecipeDiffUtilCallback(this.recipeList, newRecipeList));
    this.recipeList.addAll(recipeList);
    diffResult.dispatchUpdatesTo(this);
}
Run Code Online (Sandbox Code Playgroud)