在调用notifydatasetchanged

时间:2015-11-09 12:39:29

标签: android android-layout android-activity android-recyclerview

我有一个水平回收视图(带有LinearLayoutManager),它的子项目有一个包含在relativelayout中的imageview。 recyclerview有三个包含子项的水平行。当滚动recyclelerview时,我正在使用http调用的响应更新数据集,并在http响应回调中调用notifydatasetChanged。如果recyclerview子项的高度和宽度是固定值(例如150dp,84dp),则recyclerview的行为与预期相同,即加载新项并保持在相同的滚动位置,但如果我将recyclerview的子项的高度和宽度设置为match_parent, wrap_content,recyclerview完全刷新并滚动到第一个位置。为什么会这样? 注意:我在SO上检查了其他类似的问题,但没有一个提供可行的解决方案。

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>

4 个答案:

答案 0 :(得分:6)

我遇到了同样的问题,无法在SO上找到解决方案。该问题是由于未为LayoutManager设置RecyclerView而导致的。我知道你说你有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);

答案 1 :(得分:0)

刷新可能是因为您没有指定子视图的大小。我要做的第一件事是删除RelativeLayout,这会减少视图深度,因为它似乎没有任何用途。此外,如果recyclerView的子视图始终具有相同的大小,则将其设置在childViews本身而不是parentView,即recyclerView。你还在recyclerView上将hashFixedSize设置为true吗?

答案 2 :(得分: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);
            }

答案 3 :(得分:-1)

当您调用notifyDataSetChanged

时,可以将RecyclerView滚动到特定位置
Public class TopLevelClass

Namespace name1

    Public Class Zclass

        Public Property A As Aclass

        Public Sub New()
            Me.A = New Aclass
        End Sub

        Public NotInheritable Class Aclass
            Public Sub New()
            End Sub
        End Class

    End Class

End Namespace

Namespace name2

    Public Class Zclass

        Public Property A As Aclass

        Public Sub New()
            Me.A = New Aclass
        End Sub

        Public NotInheritable Class Aclass
            Public Sub New()
            End Sub
        End Class

    End Class

End Namespace

End Class