RecyclerView
のアイテムにビューを動的に追加しています。これらの追加されたビューは、それらが追加されたアイテムにのみ関連しているはずですが、スクロールすると問題が発生します。 View
がリサイクルされ、新しいアイテムが読み込まれたようですが、以前に追加されたビューは引き続き存在し、間違ったアイテムにのみ表示されます。
ViewHolder
が再利用されているからだと思います。そのため、追加されたアイテムは、ロードされると新しいアイテムとともに再び表示されます。
これをどのように解決しますか?
これは私の古い質問でした。賞金がそれに置かれたので、人気の急上昇と複数の新しくて無関係な答えがありました。
この回答 への私のコメントと@ CQMの私の元の質問の下のコメントの両方で述べられているように、答えはオーバーライドすることですonViewRecycled()
メソッドを実行し、そこで必要な操作を実行します。このメソッドは、ビューがリサイクルされるときに呼び出され、ここで任意のクリーンアップ操作を実行できます。
このメソッドに関するドキュメントは ここ にあります。
私の場合、ビューに添付されている非表示のTextView
を削除するだけでした。テキスト自体は削除されましたが、ビューは残りました。多くの非表示のTextView
がビューに蓄積され、スクロール時に適切にリサイクルされない場合、スクロールは遅れ始めます。
バッキングデータに基づいて、追加されたビューを追跡する必要があります。おそらく、onBindViewHolder()
に必要な追加のビューを追加し、onViewRecycled()
に存在する可能性のあるビューを削除します。次に、動的に表示する場合は、追跡している変数を表示するかどうかを変更し、notifyItemChanged()
を呼び出します。
これに基づいて:
しかし、以前に追加されたビューはまだそこにありますが、現在は間違ったアイテムにあります。
基本的に、 RecyclerView のドキュメントに従って、onBindViewHolder()
メソッド内で毎回ビューをリセットする必要があります。
たとえば、プロファイルの場合にview paramを設定するメソッドがあるとすると、同じコードは次のようになります。
if (list.get(position).getId()==PreferenceManager.getUserID())
{
// do some view change here
setViewParam(true);
}else
{
// reset the view change here
setViewParam(false);
}
つまり、ここで行っているのは、リサイクルされたViewHolderにリセットの機会を与えることです。ヘルプが必要な場合はコメントしてください!
これが使えます! setItemViewCacheSize(int size)
ここをチェック RecyclerViewDocumentation 。
オフスクリーンビューキャッシュは、接続されたアダプターの変更を常に認識しているため、LayoutManagerは、アダプターに戻って再バインドすることなく、これらのビューを変更せずに再利用できます。
NewViewの追加操作が発生するたびに、新しい子を持つアイテムのタグで情報を保存します。 (たとえば、共有設定の場合)タグ:アイテム位置onBindViewHolderで作成します。
...
SharedPreference sharedPref = getSharedPreference("text" + position, context);
SharedPreference.Editor editor = sharedPref.edit();
editor.putString("view", "ImageView");
...
アダプタをロードすると、この値が取得され、デフォルトがnullになります。その効率についてはよくわかりませんが、私は働きます。
...
String viewType = sharedPref.getString("view", null);
//it will return ImageView
たとえば、いくつかの可能なviewTypeがわかっている場合は、常にImageViewとTextViewになるので、いくつかのifステートメントを使用すれば問題ありません。
if(viewType.equals("ImageVIew")){
item(position).addView(new ImageVIew(context));
}
幸運を
子アイテムのレイアウトLinearlayout
でXML
のような空のレイアウトを取得し、スクロールするときにこの方法で特定のアイテムのLinearLayout
にビューを追加する必要があります。 LinearLayout
に追加した子ビューも、そのアイテムとともにスクロールします。
recyclerView
のアダプタクラスで、onBindViewHolder
メソッドで、別のアダプタを作成し、新しいアダプタに対して同じメソッドを実行します。
階層は、
mainRecyclerView-> item1(-> childRecyclerView1)、item2(-> childRecyclerView2)、item3(-> childRecyclerView3)
このようにして、間違った値が間違ったアイテムに表示されることなく、必要なことを達成できます。