简体   繁体   English

RecyclerView notifyDataSetChanged 滚动到顶部 position

[英]RecyclerView notifyDataSetChanged scrolls to top position

when calling notifyDataSetChanged on RecyclerView it doesn't retain the scroll position and scrolls to top, is there any solution to retain it's scroll position?RecyclerView上调用notifyDataSetChanged时,它不保留滚动 position 并滚动到顶部,是否有任何解决方案来保留它的滚动 position?

If your RecyclerView list item parent has "wrap_content" property, Recyclerview calculates the heights again and scrolls top.如果您的 RecyclerView 列表项父项具有“wrap_content”属性,则 Recyclerview 会再次计算高度并滚动顶部。

There are two solutions:有两种解决方案:

  1. Set your height a constant value like this: layout_height="100dp"将您的高度设置为一个常量值,如下所示: layout_height="100dp"
  2. Use StaggeredGridLayoutManager like this:像这样使用 StaggeredGridLayoutManager:

    mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(1, StaggeredGridLayoutManager.VERTICAL));

The second solution is more efficient and I suggest this one第二种解决方案更有效,我建议使用这个

Not sure if this solves your problem but I was having the same issue and it was because I was calling setAdapter after notify.不确定这是否解决了您的问题,但我遇到了同样的问题,这是因为我在通知后调用了 setAdapter。 So, not calling setAdapter after notify solved the problem.因此,在通知解决问题后不调用 setAdapter。

mAdapter.notifyItemRangeInserted(mAdapter.getItemCount(), list.size() - 1);
recyclerView.setAdapter(); // remove this line. 
//Do this only when you're setting the data for the first time or when adapter is null. 

As I am guessing, what you are doing is resetting the adapter to the RecyclerView and then calling notifyDataSetChanged().正如我所猜测的,您正在做的是将适配器重置为RecyclerView ,然后调用notifyDataSetChanged().

You need to pass only the dataList to the adapter by passing dataList in adapter method like adapter update(dataList) .您只需要在通过dataList通过传递到适配器dataList像适配器适配器方法update(dataList) And in this method you can assign this list to adapter list like;在这种方法中,您可以将此列表分配给适配器列表,例如;

public void update(ArrayList<Hashmap<String,String> list){
  this.mList = list;
}

You can use swapAdapter() and after call notifyDataSetChange() .您可以使用swapAdapter()并在调用notifyDataSetChange() 之后 This works for me.这对我有用。

RecycleViews will scroll back to the top on any variant of notifyDataSetChanged if they don't have a layout manager.如果notifyDataSetChanged没有布局管理器,它们将在notifyDataSetChanged任何变体上滚动回顶部。 Here's an example of how to set one.这是如何设置一个的示例。

LinearLayoutManager linearLayoutManager = new LinearLayoutManager(context, OrientationHelper.VERTICAL, false);
recycleView.setLayoutManager(linearLayoutManager);

In my case, the recyclerview was paginated.就我而言,recyclerview 是分页的。 Every time it reaches the end and loads/inserts item using notifyItemInserted, the recyclerView used to scroll.每次到达末尾并使用notifyItemInserted 加载/插入项目时,recyclerView 用于滚动。 So following worked for me:所以以下对我有用:

recycler_view.stopScroll();

As stated in the doc:如文档中所述:

Stop any current scroll in progress, such as one started by smoothScrollBy(int, int), fling(int, int) or a touch-initiated fling.停止正在进行的任何当前滚动,例如由 smoothScrollBy(int, int)、fling(int, int) 或触摸启动的 fling 启动的滚动。

notifyItemChanged() make the RecyclerView scroll and jump to UP notifyItemChanged() 使 RecyclerView 滚动并跳转到 UP

android:descendantFocusability="blocksDescendants"

Horizontal recyclerView inside vertical recyclerView generally causes that problem and this is best approach to get rid of problem.垂直 recyclerView 内的水平 recyclerView 通常会导致该问题,这是摆脱问题的最佳方法。 Don't put this attr into horizontal recyclerViews, it needs to be in only Parent (vertical RecyclerView).不要把这个属性放到水平recyclerViews中,它只需要在Parent(垂直RecyclerView)中。

Use android:descendantFocusability="blocksDescendants" in the parent recyclerView .在父 recyclerView 中使用android:descendantFocusability="blocksDescendants" It will fix the issue.它会解决这个问题。 I had a child recyclerView inside the parent recyclerView and this trick helped me.我在父 recyclerView 中有一个子 recyclerView,这个技巧帮助了我。 Also except first time you should always use notifyDataSetChanged on the adapter.此外,除了第一次,您应该始终在适配器上使用 notifyDataSetChanged。

This worked for me:这对我有用:

Set the fixed size property on the RecyclerView to "true" which prevents scroll up after calling notifyDataSetChanged on the adapter:将 RecyclerView 上的固定大小属性设置为“true”,以防止在适配器上调用 notifyDataSetChanged 后向上滚动:

mRecyclerView.setHasFixedSize(true)

You can't scroll to position without having set the adapter first.如果没有先设置适配器,您就无法滚动到位置。 Set your adapter first, even if your list is empty.即使您的列表为空,也要先设置您的适配器。 Update your list when you get the data.获取数据后更新您的列表。 Then call adapter.notifydatasetchanged() method.然后调用 adapter.notifydatasetchanged() 方法。 You can then scroll to the last position.然后您可以滚动到最后一个位置。 Let me know if this answers your question or if I have to put an answer – mmmcho让我知道这是否回答了您的问题,或者我是否必须回答 – mmmcho

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 RecyclerView 在聊天屏幕中的 notifyDataSetChanged 上滚动到顶部 - RecyclerView scrolls to top on notifyDataSetChanged in chat screen NotifyDataSetChanged刷新RecyclerView,但也会滚动。 - NotifyDataSetChanged refreshes RecyclerView but scrolls as well. RecyclerView 滚动到顶部本身 - RecyclerView scrolls to the top itself recyclerview在notifyDataSetChanged()之后滚动到顶部 - recyclerview scroll to top after notifyDataSetChanged() NestedScrollView 在 Recyclerview 调整大小时滚动到顶部 - NestedScrollView scrolls to top on Recyclerview resized 在调用notifydatasetchanged后,Recyclerview滚动到顶部 - Recyclerview scrolling to top after calling notifydatasetchanged 调用 notifyDataSetChanged() 时 RecyclerView 跳转到顶部 - RecyclerView jumps to top when notifyDataSetChanged() called RecyclerView中的RecyclerView parent.notifyDataSetChanged子RecyclerView的松散位置 - RecyclerView in RecyclerView parent.notifyDataSetChanged loose position of child RecyclerView RecyclerView notifyItemChanged(position)使应用程序崩溃,并且使用notifyDataSetChanged()没有动画 - RecyclerView notifyItemChanged(position) crashes the app and no animations with notifyDataSetChanged() 在PagerAdapter上调用notifyDataSetChanged后,TabLayout会滚动到未知位置 - TabLayout scrolls to unkown position after calling notifyDataSetChanged on PagerAdapter
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM