简体   繁体   English

在调用notifydatasetchanged后,Recyclerview滚动到顶部

[英]Recyclerview scrolling to top after calling notifydatasetchanged

I have a horizontal recyclerview (with a LinearLayoutManager) and it's child item has an imageview wrapped in a relativelayout. 我有一个水平的recyclerview(使用LinearLayoutManager),它的子项目有一个包含在relativelayout中的imageview。 The recyclerview has three horizontal rows that contain child items. recyclerview有三个包含子项的水平行。 When the recyclerview is scrolled, I'm updating the dataset with the response from an http call and calling notifydatasetChanged in the http response callback. 当滚动recyclelerview时,我正在使用http调用的响应更新数据集,并在http响应回调中调用notifydatasetChanged。 If the recyclerview child item's height and width are fixed values (Eg. 150dp, 84dp) the recyclerview behaves as intended ie, loads the new items and stays at the same scroll position but if I set height and width of recyclerview's child item as match_parent and wrap_content, the recyclerview is completely refreshed and scrolls to the first position. 如果recyclerview子项的高度和宽度是固定值(例如150dp,84dp),则recyclerview的行为与预期相同,即加载新项并保持在相同的滚动位置,但如果我将recyclerview的子项的高度和宽度设置为match_parent, wrap_content,recyclerview完全刷新并滚动到第一个位置。 Why is this happening? 为什么会这样? Note: I have checked other similar questions on SO and none of them offer a workable solution. 注意:我在SO上检查了其他类似的问题,但没有一个提供可行的解决方案。

main_layout main_layout

<android.support.v7.widget.RecyclerView
    android:id="@+id/grid_recycler_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginBottom="110dp"
    android:layout_marginLeft="15dp"
    android:layout_marginTop="80dp"
    android:background="@color/transparent"
    android:outlineProvider="bounds"
    android:elevation="8dp"
    android:padding="0dp"
    android:scrollbars="none" />
....

recycler_view_child_item recycler_view_child_item

<RelativeLayout      xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="0dp">
<ImageView
    android:id="@+id/thumbnail"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:adjustViewBounds="true"
    android:maxWidth="126dp"
    android:maxHeight="225dp"
    android:padding="0dp"/>
</RelativeLayout>

I was having the same issue and could not find a solution on SO either. 我遇到了同样的问题,无法在SO上找到解决方案。 The issue was caused by not setting a LayoutManager for the RecyclerView . 问题是由于没有为RecyclerView设置LayoutManager引起的。 I know you say you have a LinearLayoutManager . 我知道你说你有一个LinearLayoutManager But make sure you have it set up in the following way. 但请确保按以下方式设置它。 (In my case, I'm using a HorizontalGridView , but the same principle applies for RecyclerView ). (在我的例子中,我使用的是HorizontalGridView ,但同样的原则适用于RecyclerView )。

horizontalGridView = (HorizontalGridView) findViewById(R.id.gridView);
GridElementAdapter adapter = newGridElementAdapter(VenueProfileActivity.this, mDeals);
horizontalGridView.setAdapter(adapter);

HorizontalGridView.LayoutManager layoutManager = new LinearLayoutManager(VenueProfileActivity.this, LinearLayoutManager.HORIZONTAL, false);
horizontalGridView.setLayoutManager(layoutManager);
horizontalGridView.setHasFixedSize(true);

The refresh probably happens because you have not specified the size of the child views. 刷新可能是因为您没有指定子视图的大小。 First thing I would do is remove the RelativeLayout which reduces the view depth since it doesn't seem to have any purpose. 我要做的第一件事是删除RelativeLayout,这会减少视图深度,因为它似乎没有任何用途。 Also if the the child views of the recyclerView are always the same size set it on the childViews themselves instead of the parentView aka the recyclerView. 此外,如果recyclerView的子视图始终具有相同的大小,则将其设置在childViews本身而不是parentView,即recyclerView。 Also did you setHasFixedSize to true on the recyclerView? 你还在recyclerView上将hashFixedSize设置为true吗?

I had the same problem and found the answer from mossy321 useful but didn't fix everything for me. 我遇到了同样的问题,发现mossy321的答案很有用,但没有为我解决所有问题。 In my application I had a list of objects and each one had a time on it which needed to be incremented every 30 seconds or so. 在我的应用程序中,我有一个对象列表,每个对象都有一个时间,需要每30秒左右递增一次。 I ran one timer in the hosting Fragment but updating the data caused the jumping problem. 我在托管片段中运行了一个计时器,但更新数据导致跳转问题。

My recycler code is as follows: 我的回收代码如下:

 orderRecycler = (RecyclerView) rootView.findViewById(R.id.order_recycler_view);
    // use this setting to improve performance if you know that changes
    // in content do not change the layout size of the RecyclerView
    orderRecycler.setHasFixedSize(true);

    //Stops items doing a default flashing animation on individual refresh
    RecyclerView.ItemAnimator animator = orderRecycler.getItemAnimator();
    if (animator instanceof SimpleItemAnimator) {
        ((SimpleItemAnimator) animator).setSupportsChangeAnimations(false);
    }

    orderLayoutManager = new LinearLayoutManager(getActivity());
    orderRecycler.setLayoutManager(orderLayoutManager);
    orderAdapter = new OrderAdapter(orderArrayList, historyArrayList, getActivity());

    orderRecycler.setAdapter(orderAdapter);

Of note here is that the setHasFixedSize is critical. 值得注意的是setHasFixedSize是关键的。 I would guess that on data change, the system has to redraw the views forcing the jump to the top problem, but if it knows they are going to be of the same size, it can just update the changed text in this case. 我猜想在数据更改时,系统必须重新绘制视图,强制跳转到顶部问题,但如果它知道它们将具有相同的大小,则可以在这种情况下更新已更改的文本。

The other problem was that I could NOT use notifyDatasetChanged or it would still cause the same problem. 另一个问题是我不能使用notifyDatasetChanged,否则它仍然会导致同样的问题。 I had to notify for each item individually. 我必须单独通知每个项目。 This is what the item animator is for in the recycler declaration. 这是物品动画师在回收者声明中的用途。 Without that, the items would flash on update. 没有它,项目将在更新时闪烁。

 for(int i = 0; i < orderArrayList.size(); i++){
                orderAdapter.notifyItemChanged(i);
            }

当您调用notifyDataSetChanged时,可以将RecyclerView滚动到特定位置

recyclerView.scrollToPosition(array.size() - 1);

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

相关问题 recyclerview在notifyDataSetChanged()之后滚动到顶部 - recyclerview scroll to top after notifyDataSetChanged() 当我在异步任务中调用notifydatasetchanged时,我的Recyclerview滚动到顶部 - when i called notifydatasetchanged in my asynctask my Recyclerview scrolling to top RecyclerView .add() 在初始化适配器后无需调用 .notifyDataSetChanged() 即可工作 - RecyclerView .add() is working without calling .notifyDataSetChanged() after initializing adapter 调用notifydatasetchanged()之后,在Recyclerview中保持视图状态不变 - Keeping state of a view constant in Recyclerview after calling notifydatasetchanged() notifydatasetchanged后recyclerview不更新 - recyclerview not updating after notifydatasetchanged RecyclerView 在 notifyDatasetChanged() 之后闪烁 - RecyclerView blinking after notifyDatasetChanged() RecyclerView notifyDataSetChanged 滚动到顶部 position - RecyclerView notifyDataSetChanged scrolls to top position 滚动后NotifyDataSetChanged不起作用 - NotifyDataSetChanged not working after scrolling 更新适配器后,RecyclerView无法自动滚动到顶部 - RecyclerView not auto scrolling to the top after updating adapter 在 RecyclerView 中的 notifyDataSetChanged 之后是否需要 setAdapter()? - Is setAdapter() necessary after notifyDataSetChanged in RecyclerView?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM