问题 RecyclerView notifyDataSetChanged滚动到顶部位置


打电话的时候 notifyDataSetChanged 上 RecyclerView  它没有保留滚动位置并滚动到顶部,是否有任何解决方案来保持它的滚动位置?


10683
2018-03-11 17:40


起源

你找到了解决方案吗? - Siddharth Srivastava
别 呼叫 notifyDataSetChanged() 在...上 RecyclerView。使用像这样的新方法 notifyItemChanged(), notifyItemRangeChanged(), notifyItemInserted()等等...... - Xaver Kapeller
我尝试了notifyItemRangeInserted(),但即便滚动到顶部。任何想法? - Siddharth Srivastava
正如@XaverKapeller所说,我使用了notifyItemInserted(),notifyItemRangeInserted,它可以正常工作而无需将listview滚动到顶部。 - Mohamed Hatem Abdu
@MohamedHatemAbdu你有什么打算 notifyItemInserted 要么 notifyItemRangeInserted 你能解释一下你的解决方案吗? - Omid Zamani


答案:


如果您的RecyclerView列表项父项具有“wrap_content”属性,则Recyclerview会再次计算高度并向上滚动。

有两种解决方案:

  1. 将高度设置为常量值,如下所示: layout_height="100dp"
  2. 像这样使用StaggeredGridLayoutManager:

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

如果要更改带动画的项目,请在片段或活动中使用notifyItemChanged方法。不在Adapter类中:

mRecyclerView.getAdapter().notifyItemChanged(position);

第二种解决方案更有效,我建议这一点


11
2018-05-29 13:22



是的,Recycler视图在“wrap_content”的情况下计算高度,因此fix设置固定布局高度或将height设置为“match_parent”。 - anp8850


不确定这是否解决了您的问题,但我遇到了同样的问题,因为我在通知后调用了setAdapter。因此,在通知解决问题后不调用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. 

4
2018-02-08 09:14



谢谢,这是工作 - Hitesh Dhamshaniya


RecycleViews将在任何变体上滚动回到顶部 notifyDataSetChanged 如果他们没有布局管理员。这是一个如何设置一个的例子。

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

1
2018-05-20 05:07





正如我猜测的那样,你正在做的是将适配器重置为 RecyclerView 然后打电话 notifyDataSetChanged().

你只需要通过 dataList 通过传递给适配器 dataList 在适配器方法,如适配器 update(dataList)。 在这种方法中,您可以将此列表分配给适配器列表,如;

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

1
2017-07-16 13:14





就我而言,recyclerview是分页的。每次到达结尾并使用notifyItemInserted加载/插入项目时,recyclelerView用于滚动。以下为我工作:

recycler_view.stopScroll(); 

如文件中所述:

停止正在进行的当前滚动,例如启动的滚动   smoothScrollBy(int,int),fling(int,int)或触发启动的fling。


1
2018-04-12 09:58



我的订单是:1找到目标视图的位置1.1计算在插入新数据后我们的视图将在什么位置2保存当前视图的顶部偏移量3交换适配器的数据4调用notifyDataSetChanged 5调用recyclelerView stopScroll 6调用recyclelerView scrollToPositionWithOffset,其中包含调整视图的位置和最新偏移量 - deadfish


您可以通过在notifyDataSetChanged之前保存位置来保留位置,然后调用平滑滚动到保存的位置

final int currentVisibleItem = ((LinearLayoutManager) layourmanager).findFirstCompletelyVisibleItemPosition();
                           productListAdapter.notifyDataSetChanged();
                            Handler handler = new Handler();
                            handler.postDelayed(new Runnable() {
                                @Override
                                public void run() {

                    if(currentVisibleItem>-1 && currentVisibleItem<lstProducts.size())
                                    rv_products.scrollToPosition(currentVisibleItem);
                                }
                            }, 100);

0
2017-09-14 05:07





您可以使用 swapAdapter() 和电话后 notifyDataSetChange()。这对我有用。


-2
2017-11-20 13:39