web-dev-qa-db-ja.com

何がいいですか?ループ内のnotifyDataSetChangedまたはnotifyItemChangedですか?

したがって、RecyclerViewを使用したアクティビティがあり、TextView内のすべてのアイテムのRecyclerViewを変更するには、アクティビティにonClickListener()があるボタンを押します。

私はパフォーマンスの面で何が優れているのだろうと思っています:

  1. notifyDataSetChangedを使用します。
  2. Int iがList.size()より小さいような条件でループを使用します。ここで、notifyItemChangedは数回呼び出されます。

どちらの場合も、RecyclerViewアダプターでブール変数を作成します。これは、アイテムを更新する方法を知るためにonBindViewHolderによって使用されます。デフォルトではfalseであり、ボタンをクリックするとtrueになるため、onBindViewHolderは異なる方法でアイテムを更新します。

また、このアプローチが適切かどうかを知りたいです。

47
Daniel

ビューの一部を単に更新する場合は、notifyItemRangeChanged()の代わりにnotifyItemChanged()またはnotifiyDataSetChanged()を使用します。ここでの違いは、構造の変更アイテムの変更に関係しています。これはAndroid Developers _RecyclerView.Adapter_ documentation found here にあります。

2種類の変更の違いに関する別のヒントを次に示します。

データ変更イベントには、アイテムの変更と構造の変更という2つの異なるクラスがあります。アイテムの変更は、単一のアイテムのデータが更新されたが、位置の変更が発生していない場合です。構造の変更とは、データセット内でアイテムが挿入、削除、または移動されるときです。

これは前述のページから取られています。

アダプターを作成している場合、可能であれば、より具体的な変更イベントを使用する方が常に効率的です。最後の手段としてnotifyDataSetChanged()に依存してください。

したがって、明確にするためにnotifyDataSetChanged()last resortとして使用し、代わりにこれらのメソッドの1つを代わりに実行できるかどうかを自問してください。代わりに使用できる場合:

_notifyItemChanged(int)
notifyItemInserted(int)
notifyItemRemoved(int)
notifyItemRangeChanged(int, int)
notifyItemRangeInserted(int, int)
notifyItemRangeRemoved(int, int)
_

notifyDataSetChanged()はデータに基づいてすべてを再描画し、以前の仮定を行わないのに対して、他のメソッドは変更を探すだけなので、これは理にかなっています。つまり、アダプターは、必要のないさらに多くの作業を行う必要があります。これはnotifyDataSetChanged()が行うことです:

このイベントは、データセットの変更内容を指定せず、すべてのオブザーバーに、既存のすべてのアイテムと構造が無効になる可能性があることを強制します。 LayoutManagersは、すべての表示ビューを完全に再バインドおよび再レイアウトすることを強制されます。

また、これはインクリメンタルまたは範囲アプローチを使用するのが理にかなっています。テキストを変更しているため、新しいテキストをそれぞれ取得する必要があります。その場合、アダプターに変更したことを伝える必要があります。さて、ボタンをクリックしてすべての新しいテキスト値を取得し、新しいリストまたは何かを作成したら、重いnotifyDataSetChanged()を呼び出します。

63
napkinsterror

すべてのデータ項目が無効になった場合、間違いなくnotifyDataSetChanged()を呼び出します。 notifyItemChanged(mPos)を呼び出すと、notifyItemRangeChanged(mPos, 1)の呼び出しと同等になり、呼び出されるたびにrequestLayout()も呼び出されます。一方、notifyDataSetChanged()またはnotifyItemRangeChanged(0, mList.size())を呼び出す場合、requestLayout()の呼び出しは1つだけです。

あなたの質問は、何が良いですか、notifyDataSetChanged()またはnotifyItemRangeChanged(0, mList.size())の呼び出しですか?そのために私は答えがありません。

13
Ari

notifyItemChanged(mPos)は、現在表示されていなくても、対応する位置に対してonBindVieHolderをトリガーすることに気付きました。

私にとって、すべての要素のループで呼び出すと、表示されているものだけを再描画するnotifyDatasetChangedよりもコストがかかりました。

そのため、大規模なデータセットには注意してください。

5