当notifyDataSetChanged()称为

时间:2019-12-22 07:12:11

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

我有一个片段,其中包含swipeRefreshLayout和无穷大recyclerView。我的片段布局代码类似于:

<androidx.constraintlayout.widget.ConstraintLayout
        .
        .
        .
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        android:clickable="true"
        android:focusable="true"
        android:focusableInTouchMode="true">


    <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
        .
        .
        .
         android:layout_width="0dp"
         android:layout_height="0dp"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toBottomOf="parent" >

        <androidx.recyclerview.widget.RecyclerView
                android:id="@+id/rv_main_news"
                android:layout_width="match_parent"
                android:layout_height="match_parent"/>

    </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

我在onViewCreated()中设置了recyclerView的适配器,并在notifyDataSetChanged()中调用了onResume()。在某些设备中,例如三星Galaxy A5,当用户返回片段并调用notifyDataSetChanged时,recyclerView移至顶部并显示第一项。

如何防止这种情况? 预先感谢。

更新:这是我的onResume()代码,调用notifyDataSetChanged()

override fun onResume() {
super.onResume()
    if (rv.adapter != null)
        (rv.adapter as MyAdapter).apply {
            fontSize = Options.getFontSize()
            notifyDataSetChanged()
        }
}

2 个答案:

答案 0 :(得分:0)

您可以在更新时尝试保存RV的滚动状态:

 val recyclerViewState = rv.layoutManager?.onSaveInstanceState()
 adapter.notifyDataSetChanged()            
 rv?.layoutManager?.onRestoreInstanceState(recyclerViewState)

答案 1 :(得分:0)

可以预期,当notifyDataSetChanged调用时,整个视图都将刷新。当您返回片段时,onResume会被调用,随后您的notifyDataSetChanged也将被调用。这就是为什么您看到第一项。

因此,为防止发生这种情况,您需要在更改或更新整个数据时调用notifyDataSetChanged

我可以建议您一些方式。

从onResume删除notifyDataSetChanged并使用diffUtil进行recyclerView数据更新。它将仅更新您更改的项目。仅在必要时更新数据,例如,如果您更新详细信息中的任何数据并想要在列表中更新,则可以覆盖onActivityResult并在此处通知您的列表。或者,您可以发送广播并在列表片段中接收它,并通知您列表。

预先感谢,希望能对您有所帮助。