3

我有一个水平recyclerview(与一个LinearLayoutManager),它的子项目有一个imageview包裹在一个相关布局中。 recyclerview有三个包含子项的水平行。当滚动回滚视图时,我使用来自http调用的响应更新数据集,并在http响应回调中调用notifydatasetChanged。如果recyclerview子项的高度和宽度是固定值(例如150dp,84dp),recyclerview的行为就像预期的那样,即加载新项目并停留在同一个滚动位置,但如果我将recyclerview的子项的高度和宽度设置为match_parent,并且wrap_content,recyclerview完全刷新并滚动到第一个位置。这是为什么发生? 注意:我已经检查过其他类似的问题,但都没有提供可行的解决方案。Recyclerview在调用notifydatasetchanged后滚动到顶部

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

<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> 

回答

0

的刷新可能是因为你没有指定的子视图大小。我要做的第一件事就是删除RelativeLayout,它减少了视图深度,因为它似乎没有任何目的。此外,如果recyclerView的子视图始终具有相同大小,则将其设置在childViews本身而不是parentView(也称为recyclerView)上。您是否也在recyclerView上将HasFixedSize设置为true?

+0

删除相对布局。由于我将recyclerview的尺寸设置为与父母的尺寸相匹配,因此回收站视图的尺寸可能因设备而异。所以我无法为子视图设置固定大小。回收站视图有三行,因此我设置了childview的高度以匹配父级和宽度以包装内容,以避免回收站视图中子视图之间出现空间。 – Neanderthal

+0

此外,我已将setHasFixedSize设置为true。 – Neanderthal

-1

您可以滚动RecyclerView到特定位置,当你叫notifyDataSetChanged

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

我有同样的问题,但没有找到一个解决方案,因此无论是。该问题是由于RecyclerView未设置LayoutManager而导致的。我知道你说你有一个LinearLayoutManager。但请确保您按照以下方式进行设置。 (在我的情况下,我使用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); 
0

我有同样的问题,发现从mossy321有用的答案有用,但没有解决我的一切。在我的应用程序中,我有一个对象列表,每个对象都有一段时间,需要每隔30秒左右递增一次。我在宿主片段中运行了一个计时器,但更新数据导致跳跃问题。

我回收的代码如下:

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); 

这里注意到的是,setHasFixedSize是至关重要的。我猜想在数据更改时,系统必须重新绘制视图,以强制跳转到最高的问题,但如果它知道它们将具有相同的大小,则可以在此情况下更新已更改的文本。

另一个问题是我不能使用notifyDatasetChanged或它仍然会导致同样的问题。我必须分别通知每件物品。这是动画师在回收商声明中使用的内容。没有这些,项目会在更新时闪烁。

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