2015-11-18 8 views
37

私はRecyclerViewのアクティビティを持っており、RecyclerViewのすべてのアイテムのTextViewを、アクティビティのonClickListener()というボタンを押して変更したいとします。何が良いですか?ループ内のnotifyDataSetChangedまたはnotifyItemChanged?

私は、パフォーマンスの面で優れているかと思っています:

  1. notifyDataSetChangedのものを使用してください。
  2. intのような条件でループを使用すると、List.size()より小さい。notifyItemChangedが数回呼び出されることがあります。私はアイテムを更新する方法を知ってonBindViewHolderで使用されRecyclerViewアダプタのboolean変数を作成し、両方のケースで

。デフォルトではfalseで、ボタンをクリックするとtrueになるので、onBindViewHolderは異なる方法で項目を更新します。

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

+0

'notifyDataSetChanged'は表示可能なビューを再描画します。私があなたの要求を正しく理解しているなら、私はそれを選ぶでしょう。 – dharms

+0

RecyclerViewコードをまだ見て、 'notifyDataSetChanged'で何が起きているのか確認しましたか?特定のアイテムを変更しない限り、退屈なように見える個々のアイテムに呼び出すのではなく、データセット全体を一度に再検証するため、名前に基づいて(そして専門知識ではなく) – AdamMc331

+0

@ McAdam331私のRecyclerViewのアイテムはCardViewでTextViewが入っています。すべての目に見えるカードのTextViewを一度に変更したい。 – Daniel

答えて

44

ビューの一部を更新するだけの場合は、notifiyDataSetChanged()の代わりにnotifyItemRangeChanged()またはnotifyItemChanged()を使用します。ここでの違いは、の構造変更の変更点との関係です。これはアンドロイドデベロッパーRecyclerView.Adapterのドキュメントhereにあります。ここで

変更の2つのタイプの違いの他ちらほらです:データ変更イベントの2つの異なるクラスがあります

、アイテムは 、構造上の変更を変更します。アイテムの変更は、1つのアイテムに のデータが更新されていても、位置の変更が発生していない場合です。構造 は、データがアイテム内に挿入、削除、または移動されたときに変更されます。

これは、アダプターを作成している場合、常にあなたができる場合 より具体的な変更イベントを使用する方が効率的になります

、その上記のページから取得されます。最後の手段として notifyDataSetChanged()を依頼してください。

だから最後として使用notifyDataSetChanged()を明確にし、代わりにあなたの代わりにこれらのメソッドのいずれかをプリフォームすることができた場合、あなたは代わりにそれを使用できるかどうか自問する:

notifyItemChanged(int) 
notifyItemInserted(int) 
notifyItemRemoved(int) 
notifyItemRangeChanged(int, int) 
notifyItemRangeInserted(int, int) 
notifyItemRangeRemoved(int, int) 

せましたなぜなら、notifyDataSetChanged()はデータに基づいてすべてを再描画しようとし、以前の仮定はしていないからです。他の方法は変更を探します。つまり、アダプターは必要ではない多くの作業を行う必要があります。これはnotifyDataSetChanged()が何をするかである:このイベントは は、すべての既存のアイテムと構造 は、もはや有効ではないかもしれないことを前提とするために、任意のオブザーバーを強制的に、変更されたデータセットについての内容を指定しない

。 LayoutManagersは、 を完全に再バインドし、すべての表示可能なビューを再レイアウトするように強制されます。

これはまた、あなたがテキストを変更しているので、あなたがそれぞれの新しいテキストを取りに行く必要があるとあなたは、アダプタを伝える必要があることを行うとき、あなたがそれを変更し、増分または範囲のアプローチを使用することに意味があります。今、ボタンをクリックして新しいテキスト値をすべて取得し、新しいリストなどを作成した場合は、重い番号notifyDataSetChanged()を呼び出します。

+0

私が数日前に経験したことは、notifyItenChanged(x)を呼び出すことは、xのためのonBindViewHolderを呼び出すだけでなく、ビューホルダーのハッシュが変更された他のアイテムに対しても、Androidのバグかどうかまだ分かりません。それは共通の行動です。 – David

9

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

あなたの質問は、現在はnotifyDataSetChanged()またはnotifyItemRangeChanged(0, mList.size())に電話してください。私は答えがありません。

2

私は、notifyItemChanged(mPos)が現在対応していない位置でもonBindVieHolderをトリガーしていることに気付きました。

私にとって、すべての要素のループでそれを呼び出すのは、目に見えるものだけを再描画するnotifyDatasetChangedよりも高価でした。

大きなデータセットには注意が必要です。

関連する問題