如何在调用notifyDataSetChanged后防止RecyclerView自动滚动?

7
我有一个包含多种项目类型的RecyclerView。它长这样:
  • 07/21/2017
  • 消息1
  • 消息2
  • 消息3
  • 07/22/2017
  • 消息4
  • 新消息标题
  • 消息5
  • 消息6
当新消息到达时,我按日期排序并调用notifyDataSetChanged()。它可以正常工作,但它会自动滚动RecyclerView到新项目的高度。在这种情况下,我不能使用notifyItemInserted(),因为我不知道在排序后的位置。
如何在调用notifyDataSetChanged()后强制RecyclerView不滚动,而不调用notifyItemInserted()

你不想调用notifyItemInserted()是为什么呢? - phatnhse
因为我按日期对项目进行排序,不知道在排序后插入的项目位置。 - BArtWell
你的视图可以从起始项进行更改,对吗? - phatnhse
是的,如果新项目具有最小日期。 - BArtWell
3个回答

12

有四种方法可以尝试。因为我不知道您的视图高度是多少,所以我不能确定它是否有效。但是让我们试一试吧。

I. 您不知道具体要更改哪个项目,但您知道更改的范围

mAdapter.notifyItemInserted(position);                 
mAdapter.notifyItemRangeChanged(0, list.size());

二. 在调用notifyDataSetChanged()之前清空列表

yourList.clear();
mAdapter.notifyDataSetChanged();

III. 在添加新项目之前/之后保存/重置RecyclerView的状态

    // Save state
    private Parcelable recyclerViewState;
    recyclerViewState = recyclerView.getLayoutManager().onSaveInstanceState();

    // Restore state
    recyclerView.getLayoutManager().onRestoreInstanceState(recyclerViewState);

IV. 使用此函数

mAdapter.notifyItemRangeChanged(0, list.size());

第一种方法非常棒,正是我所需要的! - Acuna
1
太棒了!第三种解决方案对我有用,同时我也在适配器中使用了DiffUtil。谢谢! - Bill

1

你玩过myRecView.getLayoutManager().setStackFromEnd(boolean)吗?

如果你能确定新项目是否在可见部分的排序上方或下方插入,并根据此调用setStackFromEnd(),传递true或false,也许你可以避免滚动。

我不知道它是否真的有效....


0

您可以使用list.indexOf(yourItem)来确定新项插入的位置。然后,您可以调用notifyItemInserted()


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接