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

时间:2017-12-04 11:48:16

标签: android android-recyclerview recycler-adapter

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

所以我的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;

}

1 个答案:

答案 0 :(得分:1)

我不确定这个答案但是,我认为你调用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);
}