RecyclerView
name__内の特定のアイテムを更新しようとしています。
ストーリー:ユーザーがアイテムをクリックするたびにAlertDialog
name__が表示されます。ユーザーは[OK]ボタンをクリックしてテキストを入力できます。このアイテムにこのテキストを表示し、見えないImageView
name__を表示したい - XMLおよびアダプタで宣言されたViewHolder
-
私はAlertDialog
name__のポジティブボタンでこの関数を使って項目を更新しました:
private void updateListItem(int position) {
View view = layoutManager.findViewByPosition(position);
ImageView medicineSelected = (ImageView) view.findViewById(R.id.medicine_selected);
medicineSelected.setVisibility(View.VISIBLE);
TextView orderQuantity = (TextView) view.findViewById(R.id.order_quantity);
orderQuantity.setVisibility(View.VISIBLE);
orderQuantity.setText(quantity + " packet added!");
medicinesArrayAdapter.notifyItemChanged(position);
}
しかし、このコードは渡された位置のitemViewを変更するだけでなく、他のitemViewも変更します。
特定のitemViewをクリックして正しく変更するにはどうすればよいですか?
RecyclerView.Adapterクラスの notifyItemChanged(int position)
メソッドを使用できます。ドキュメントから:
位置の項目が変更されたことを登録オブザーバに通知します。 notifyItemChanged(position、null);を呼び出すのと同じです。
これはアイテム変更イベントであり、構造変更イベントではありません。これは、位置のデータの反映が古くなっているため、更新する必要があることを示しています。位置にある項目は同じIDを保持します。
あなたはすでにポジションを持っているので、それはあなたのために働くはずです。
notifyItemChanged(updateIndex)
でアダプタに変更を通知してください「羊が好き」というように「羊」の項目を変更します。
String newValue = "I like sheep.";
int updateIndex = 3;
data.set(updateIndex, newValue);
adapter.notifyItemChanged(updateIndex);
もっと多くの例を挙げた私の完全な答えは ここ です。
私はこれに対処する方法についてのアイデアがあると思います。更新は、正確な位置で削除して置き換えるのと同じです。それで、私は最初に以下のコードを使ってその位置からアイテムを取り除きます:
public void removeItem(int position){
mData.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, mData.size());
}
それから私は以下に示すようにその特定の位置にアイテムを追加します。
public void addItem(int position, Landscape landscape){
mData.add(position, landscape);
notifyItemInserted(position);
notifyItemRangeChanged(position, mData.size());
}
私は今これを実装しようとしています。私が通っているとき、私はあなたにフィードバックをするでしょう!
私はこの問題を解決するために、変更が必要なアイテムの位置を把握し、それからアダプター呼び出しを行いました。
public void refreshBlockOverlay(int position) {
notifyItemChanged(position);
}
これは、この特定の位置にあるこの特定の項目に対してonBindViewHolder(ViewHolder holder、int position)を呼び出します。
変更したテキストをモデルデータリストに追加します
mdata.get(position).setSuborderStatusId("5");
mdata.get(position).setSuborderStatus("cancelled");
notifyItemChanged(position);
以下の解決策は私のために働いた:
RecyclerView項目で、ユーザーはボタンをクリックしますが、TextViewのような別のビューはアダプタに直接通知することなく更新されます。
NotifyDataSetChanged()メソッドを使用せずにこれに適した解決策を見つけました。このメソッドはrecyclerViewのすべてのデータをリロードするため、アイテム内に画像またはビデオがある場合はリロードされ、ユーザーエクスペリエンスは良くありません。
これは、ImageViewのようなアイコンをクリックし、+ 1を追加した後にcount updateのように表示されるように単一のTextViewのみを更新することです(同じ項目で同じ方法でより多くのビューを更新できます)。
// View holder class inside adapter class
public class MyViewHolder extends RecyclerView.ViewHolder{
ImageView imageViewLike;
public MyViewHolder(View itemView) {
super(itemView);
imageViewLike = itemView.findViewById(R.id.imageViewLike);
imageViewLike.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int pos = getAdapterPosition(); // Get clicked item position
TextView tv = v.getRootView().findViewById(R.id.textViewLikeCount); // Find textView of recyclerView item
resultList.get(pos).setLike(resultList.get(pos).getLike() + 1); // Need to change data list to show updated data again after scrolling
tv.setText(String.valueOf(resultList.get(pos).getLike())); // Set data to TextView from updated list
}
});
}
個人的に私のために働いてきた方法は、その項目の変更に対処するためにrecyclerviewのアダプタメソッドを使うことです。
これは、これと同じような方法で行われます。あなたのカスタムリサイクラーのビューでは、次のようにメソッドを作成します。
public void modifyItem(final int position, final Model model) {
mainModel.set(position, model);
notifyItemChanged(position);
}
アダプタクラスのonBindViewHolderメソッドで、下のコードのようにViewHolderをsetIsRecyclable(false)に設定します。
@Override
public void onBindViewHolder(RecyclerViewAdapter.ViewHolder p1, int p2)
{
// TODO: Implement this method
p1.setIsRecyclable(false);
// Then your other codes
}
1つのオブジェクトを作成して、アダプターで使用するリストに追加する場合、アダプターのリストの1つの要素を変更すると、他のすべてのアイテムも変更されます。その単一オブジェクトの個別のコピーを保持します。
クリックしたときに警告ダイアログボックスに次のコードを追加するだけです。
recyclerData.add(position, updateText.getText().toString());
recyclerAdapter.notifyItemChanged(position);