Inilah XML untuk item saya di dalam RecyclerView
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="@+id/cvItems"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:layout_margin="2dp"
card_view:cardElevation="0dp"
card_view:contentPadding="0dp"
card_view:cardBackgroundColor="#FFFFFF"
>
<LinearLayout
android:orientation="horizontal"
android:layout_height="fill_parent"
android:layout_width="fill_parent">
<TextView
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_weight="0.8"
android:id="@+id/tvContent"
android:textSize="15dp"
android:paddingLeft="5dp"
android:paddingRight="5dp" />
<CheckBox
android:id="@+id/cbSelect"
android:layout_width="0dip"
android:layout_weight="0.2"
android:layout_height="match_parent"
android:button="@drawable/cb_checked"
android:gravity="center_horizontal"
android:textAlignment="center"
android:layout_gravity="center_horizontal" />
</LinearLayout>
</android.support.v7.widget.CardView>
Dan inilah adaptor RecyclerView yang memekarkan tata letak di atas untuk setiap itemnya:
public class AdapterTrashIncome extends RecyclerView.Adapter<AdapterTrashIncome.ViewHolder> {
private ArrayList<ObjectIncome> myItems = new ArrayList<>();
public AdapterTrashIncome(ArrayList<ObjectIncome> getItems, Context context){
try {
mContext = context;
myItems = getItems;
}catch (Exception e){
Log.e(FILE_NAME, "51: " + e.toString());
e.printStackTrace();
}
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView tvContent;
public CheckBox cbSelect;
public ViewHolder(View v) {
super(v);
tvContent = (TextView) v.findViewById(R.id.tvContent);
cbSelect = (CheckBox) v.findViewById(R.id.cbSelect);
}
}
@Override
public void onBindViewHolder(ViewHolder holder, final int position) {
final ObjectIncome objIncome = myItems.get(position);
String content = "<b>lalalla</b>";
holder.tvContent.setText(Html.fromHtml(content));
}
}
Masalahnya adalah, katakanlah saya memiliki 10 item di dalam RecyclerView. Ketika saya mencentang kotak centang pada item 1,2,3 lalu saya scroll ke bawah RecyclerView, tiba-tiba beberapa item lain misalnya item 8,9 dicentang. Dan ketika saya menggulir ke atas lagi, item 1 dan 3 dicentang tetapi bukan item 2. Anda tahu mengapa ini terjadi?
Jawaban:
Itu adalah perilaku yang diharapkan. Anda tidak menyetel kotak centang Anda dipilih atau tidak. Anda memilih satu dan View holder tetap memilihnya. Anda dapat menambahkan variabel boolean ke dalam objek ObjectIncome Anda dan mempertahankan status pemilihan item Anda.
Anda dapat melihat contoh saya. Anda bisa melakukan sesuatu seperti itu:
public class AdapterTrashIncome extends RecyclerView.Adapter<AdapterTrashIncome.ViewHolder> { private ArrayList<ObjectIncome> myItems = new ArrayList<>(); public AdapterTrashIncome(ArrayList<ObjectIncome> getItems, Context context){ try { mContext = context; myItems = getItems; }catch (Exception e){ Log.e(FILE_NAME, "51: " + e.toString()); e.printStackTrace(); } } public class ViewHolder extends RecyclerView.ViewHolder { public TextView tvContent; public CheckBox cbSelect; public ViewHolder(View v) { super(v); tvContent = (TextView) v.findViewById(R.id.tvContent); cbSelect = (CheckBox) v.findViewById(R.id.cbSelect); } } @Override public void onBindViewHolder(ViewHolder holder, final int position) { final ObjectIncome objIncome = myItems.get(position); String content = "<b>lalalla</b>"; holder.tvContent.setText(Html.fromHtml(content)); //in some cases, it will prevent unwanted situations holder.cbSelect.setOnCheckedChangeListener(null); //if true, your checkbox will be selected, else unselected holder.cbSelect.setChecked(objIncome.isSelected()); holder.cbSelect.setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { //set your object's last status objIncome.setSelected(isChecked); } }); } }
sumber
holder.cbSelect.setOnCheckedChangeListener(null);
sebelumnyaholder.cbSelect.setChecked(objIncome.isSelected())
onBindViewHolder
.@Override public void onBindViewHolder(final ItemHolder holder, int position) { holder.checkBox.setOnCheckedChangeListener(null); holder.checkBox.setSelected(list.get(position).isSelected()); holder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { list.get(holder.getAdapterPosition()).setSelected(isChecked); } });
Singkatnya, ini karena mendaur ulang tampilan dan menggunakannya lagi!
bagaimana Anda bisa menghindari itu:
1. Di
onBindViewHolder
centang apakah Anda harus mencentang atau menghapus centang pada kotak. jangan lupa untuk meletakkan keduanya jika dan lainnyaif (...) holder.cbSelect.setChecked(true); else holder.cbSelect.setChecked(false);
myItems
larik Anda ! jadi setiap kali tampilan baru ditampilkan, itu membaca patung terbaru dari objek tersebut.sumber
isChecked
false
untuk semua kumpulan data di awal, laluonCheckChanged
saya baru saja memperbaruiisChecked
nilainya ketrue
ataufalse
dan seperti yang diceritakan dalam implementasi jawaban yang centangnya dicentang atau tidak.GUNAKAN INI HANYA JIKA ANDA MEMILIKI JUMLAH BARANG TERBATAS DALAM TAMPILAN DAUR ULANG.
Saya mencoba menggunakan nilai boolean dalam model dan mempertahankan status kotak centang, tetapi tidak membantu dalam kasus saya. Apa yang berhasil bagi saya adalah this.setIsRecyclable (false);
public class ComponentViewHolder extends RecyclerView.ViewHolder { public MyViewHolder(View itemView) { super(itemView); .... this.setIsRecyclable(false); }
Penjelasan lebih lanjut tentang ini dapat ditemukan di sini https://developer.android.com/reference/android/support/v7/widget/RecyclerView.ViewHolder.html#isRecyclable ()
CATATAN: Ini adalah solusi. Untuk menggunakannya dengan benar, Anda dapat merujuk dokumen yang menyatakan "Panggilan ke setIsRecyclable () harus selalu dipasangkan (satu panggilan ke setIsRecyclabe (false) harus selalu dicocokkan dengan panggilan selanjutnya ke setIsRecyclable (true)). Pasangan panggilan dapat disarangkan , karena negara bagian dihitung referensi secara internal. " Saya tidak tahu bagaimana melakukan ini dalam kode, jika seseorang dapat memberikan kode lebih lanjut tentang ini.
sumber
Cukup tambahkan dua metode penggantian
RecyclerView
@Override public long getItemId(int position) { return position; } @Override public int getItemViewType(int position) { return position; }
sumber
Anda bisa menggunakan kelas Model untuk melacak setiap kotak centang item recyclerView. Referensi lengkap berasal dari: RecyclerView Checkbox Android
setTag dan getTag digunakan untuk melacak status kotak centang. Lihat tautan referensi lengkap untuk informasi lebih lanjut. Ini juga mengajarkan cara mengirim item yang dicentang ke NEXTACTIVITY .
Membuat model
public class Model { private boolean isSelected; private String animal; public String getAnimal() { return animal; } public void setAnimal(String animal) { this.animal = animal; } public boolean getSelected() { return isSelected; } public void setSelected(boolean selected) { isSelected = selected; } }
buat integer.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <integer name="btnplusview">1</integer> <integer name="btnpluspos">2</integer> </resources>
Akhirnya adaptor terlihat seperti ini:
import android.content.Context; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.CheckBox; import android.widget.TextView; import android.widget.Toast; import java.util.ArrayList; public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.MyViewHolder> { private LayoutInflater inflater; public static ArrayList<Model> imageModelArrayList; private Context ctx; public CustomAdapter(Context ctx, ArrayList<Model> imageModelArrayList) { inflater = LayoutInflater.from(ctx); this.imageModelArrayList = imageModelArrayList; this.ctx = ctx; } @Override public CustomAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = inflater.inflate(R.layout.rv_item, parent, false); MyViewHolder holder = new MyViewHolder(view); return holder; } @Override public void onBindViewHolder(final CustomAdapter.MyViewHolder holder, int position) { holder.checkBox.setText("Checkbox " + position); holder.checkBox.setChecked(imageModelArrayList.get(position).getSelected()); holder.tvAnimal.setText(imageModelArrayList.get(position).getAnimal()); // holder.checkBox.setTag(R.integer.btnplusview, convertView); holder.checkBox.setTag(position); holder.checkBox.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Integer pos = (Integer) holder.checkBox.getTag(); Toast.makeText(ctx, imageModelArrayList.get(pos).getAnimal() + " clicked!", Toast.LENGTH_SHORT).show(); if (imageModelArrayList.get(pos).getSelected()) { imageModelArrayList.get(pos).setSelected(false); } else { imageModelArrayList.get(pos).setSelected(true); } } }); } @Override public int getItemCount() { return imageModelArrayList.size(); } class MyViewHolder extends RecyclerView.ViewHolder { protected CheckBox checkBox; private TextView tvAnimal; public MyViewHolder(View itemView) { super(itemView); checkBox = (CheckBox) itemView.findViewById(R.id.cb); tvAnimal = (TextView) itemView.findViewById(R.id.animal); } }
}
sumber
Menggunakan Kotlin, satu-satunya hal yang memecahkan masalah ini bagi saya adalah menghapus
OnCheckedChangeListener
sebelum mengatur variabel dan kemudian membuat yang baruOnCheckedChangeListener
setelahchecked
ditetapkan.Saya melakukan hal berikut di saya
RecyclerView.ViewHolder
task.setOnCheckedChangeListener(null) task.isChecked = item.status task.setOnCheckedChangeListener { _: CompoundButton, checked: Boolean -> item.status = checked ... do more stuff ... }
sumber
Seperti yang dinyatakan di atas, status objek yang diperiksa harus dimasukkan dalam properti objek. Dalam beberapa kasus, Anda mungkin juga perlu mengubah status pemilihan objek dengan mengklik objek itu sendiri dan membiarkan Kotak Centang menginformasikan tentang keadaan sebenarnya (baik dipilih atau tidak). Kotak centang kemudian akan menggunakan status objek pada posisi sebenarnya dari adaptor yang diberikan, yaitu (secara default / dalam banyak kasus) posisi elemen dalam daftar.
Cek potongan dibawah ini, semoga bermanfaat.
import android.content.Context; import android.graphics.Bitmap; import android.net.Uri; import android.provider.MediaStore; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.ImageView; import java.io.File; import java.io.IOException; import java.util.List; public class TakePicImageAdapter extends RecyclerView.Adapter<TakePicImageAdapter.ViewHolder>{ private Context context; private List<Image> imageList; public TakePicImageAdapter(Context context, List<Image> imageList) { this.context = context; this.imageList = imageList; } @Override public TakePicImageAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view= LayoutInflater.from(context).inflate(R.layout.image_item,parent,false); return new ViewHolder(view); } @Override public void onBindViewHolder(final TakePicImageAdapter.ViewHolder holder, final int position) { File file=new File(imageList.get(position).getPath()); try { Bitmap bitmap= MediaStore.Images.Media.getBitmap(context.getContentResolver(), Uri.fromFile(file)); holder.image.setImageBitmap(bitmap ); } catch (IOException e) { e.printStackTrace(); } holder.selectImage.setOnCheckedChangeListener(null); holder.selectImage.setChecked(imageList.get(position).isSelected()); holder.selectImage.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { holder.selectImage.setChecked(isChecked); imageList.get(position).setSelected(isChecked); } }); holder.image.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (imageList.get(position).isSelected()) { imageList.get(position).setSelected(false); holder.selectImage.setChecked(false); }else { imageList.get(position).setSelected(true); holder.selectImage.setChecked(true); } } }); } @Override public int getItemCount() { return imageList.size(); } public class ViewHolder extends RecyclerView.ViewHolder { public ImageView image;public CheckBox selectImage; public ViewHolder(View itemView) { super(itemView); image=(ImageView)itemView.findViewById(R.id.image); selectImage=(CheckBox) itemView.findViewById(R.id.ch); } } }
sumber
Dalam kasus saya ini berhasil.
@Override public void onViewRecycled(MyViewHolder holder) { holder.checkbox.setChecked(false); // - this line do the trick super.onViewRecycled(holder); }
sumber
Gunakan larik untuk menampung status item
Dalam adaptor, gunakan Map atau SparseBooleanArray (yang mirip dengan map tetapi merupakan pasangan nilai kunci int dan boolean) untuk menyimpan status semua item dalam daftar item kami dan kemudian gunakan kunci dan nilai untuk membandingkan saat mengubah status yang dicentang
Di Adapter, buat file
SparseBooleanArray
// sparse boolean array for checking the state of the items private SparseBooleanArray itemStateArray= new SparseBooleanArray();
lalu di item click handler
onClick()
gunakan status item di itemStateArray untuk memeriksa sebelum toggling, berikut ini contohnya@Override public void onClick(View v) { int adapterPosition = getAdapterPosition(); if (!itemStateArray.get(adapterPosition, false)) { mCheckedTextView.setChecked(true); itemStateArray.put(adapterPosition, true); } else { mCheckedTextView.setChecked(false); itemStateArray.put(adapterPosition, false); } }
juga, gunakan larik boolean renggang untuk menyetel status yang dicentang saat tampilan terikat
@Override public void onBindViewHolder(ViewHolder holder, int position) { holder.bind(position); } @Override public int getItemCount() { if (items == null) { return 0; } return items.size(); } void loadItems(List<Model> tournaments) { this.items = tournaments; notifyDataSetChanged(); } class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { CheckedTextView mCheckedTextView; ViewHolder(View itemView) { super(itemView); mCheckedTextView = (CheckedTextView) itemView.findViewById(R.id.checked_text_view); itemView.setOnClickListener(this); } void bind(int position) { // use the sparse boolean array to check if (!itemStateArray.get(position, false)) { mCheckedTextView.setChecked(false);} else { mCheckedTextView.setChecked(true); } }
dan adaptor terakhir akan seperti ini
sumber
Anda perlu memisahkan interaksi onBindViewHolder (logika) dengan CheckBox dan interaksi pengguna dengan checkbox. Saya menggunakan OnCheckedChangeListener untuk interaksi pengguna (jelas) dan ViewHolder.bind () untuk logika, itulah mengapa Anda perlu mengatur pendengar yang dicentang ke null sebelum menyiapkan pemegang dan setelah pemegang siap - konfigurasikan pendengar yang diperiksa untuk interaksi pengguna.
boolean[] checkedStatus = new boolean[numberOfRows]; @Override public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) { final ViewHolderItem itemHolder = (ViewHolderItem) holder; //holder.bind should not trigger onCheckedChanged, it should just update UI itemHolder.checkBox.setOnCheckedChangeListener(null); itemHolder.bind(position); itemHolder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if (isChecked) { checkedStatus[holder.getAdapterPosition()] = true; performCheckedActions(); //your logic here } else { checkedStatus[holder.getAdapterPosition()] = false; performUncheckedActions(); //your logic here } } }); } public void bind(int position) { boolean checked = checkedStatus[position]; if (checked) { checkBox.setChecked(false); } else { checkBox.setChecked(true); } }
sumber
Saya merekomendasikan agar tidak digunakan
checkBox.setOnCheckedChangeListener
dalamrecyclerViewAdapter
. Karena saat menggulir recyclerView,checkBox.setOnCheckedChangeListener
akan diaktifkan oleh adaptor. Tidak aman . Sebaliknya, gunakancheckBox.setOnClickListener
untuk berinteraksi dengan input pengguna.Sebagai contoh:
public void onBindViewHolder(final ViewHolder holder, int position) { /* . . . . . . */ holder.checkBoxAdapterTasks.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { boolean isChecked = holder.checkBoxAdapterTasks.isChecked(); if(isChecked){ //checkBox clicked and checked }else{ //checkBox clicked and unchecked } } }); }
sumber
Masalah dari solusi ini yang saya temukan adalah, dengan membuat array global statis dan menggunakannya dalam "onBindViewHolder" ADAPER CLASS, di mana saya membuat semua varaibles global / objek yang dibutuhkan.
public class RVAdapter extends RecyclerView.Adapter<RVAdapter.PersonViewHolder> { private Context context; public static class PersonViewHolder extends RecyclerView.ViewHolder { CardView cv; TextView question,category; TextView personAge; ImageView upvote; Button b1; public static int k; private int visibleThreshold = 5; public static int i=0; static int check[]; //Static array PersonViewHolder(View itemView,int i) { super(itemView); if(i==PersonViewHolder.k) { b1=(Button)itemView.findViewById(R.id.loadmore); } else { cv = (CardView)itemView.findViewById(R.id.cv); question = (TextView)itemView.findViewById(R.id.question); category = (TextView)itemView.findViewById(R.id.text_categ); personAge = (TextView)itemView.findViewById(R.id.text1); upvote = (ImageView)itemView.findViewById(R.id.upvote); } } }
Di sini (DALAM PEMBANGUN RVADAPTER CLASS) saya memberi ukuran pada array sama dengan ukuran / tidak item yang akan saya tampilkan di tampilan pendaur ulang
List<Person> persons; RVAdapter(List<Person> persons){ this.persons = persons; PersonViewHolder.check=new int[persons.size()]; PersonViewHolder.k=persons.size(); }
BindViewHolder, I, Menerapkan konsep ini pada tombol, ketika saya mengklik tombol, gambar latar belakang tombol berubah. Objek tombol yang saya gunakan adalah nama sebagai "upvote", karena "i" memegang posisi setiap item dalam tampilan recycler, saya menggunakannya sebagai indeks array yang berfungsi sebagai bendera dan yang melacak status elemen.
@Override public void onBindViewHolder(final PersonViewHolder personViewHolder, final int i) { if(i==PersonViewHolder.k) { personViewHolder.b1.setText("load more"); } else { personViewHolder.question.setText(persons.get(i).name); personViewHolder.personAge.setText(persons.get(i).age); if(personViewHolder.check[i]==0) {personViewHolder.upvote.setBackgroundResource(R.drawable.noupvote); } else { personViewHolder.upvote.setBackgroundResource(R.drawable.upvote); } personViewHolder.upvote.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if(personViewHolder.check[i]==0) {personViewHolder.check[i]=1; personViewHolder.upvote.setBackgroundResource(R.drawable.upvote); } else {personViewHolder.check[i]=0; personViewHolder.upvote.setBackgroundResource(R.drawable.noupvote); } } }); // personViewHolder.personPhoto.setImageResource(persons.get(i).photoId); } }
sumber
Saya pernah mengalami masalah yang sama. Ketika saya mengklik tombol sakelar item di recyclerView saya, tombol Toggle dicentang muncul di setiap item ke-10 (misalnya jika diklik di item dengan indeks 0, item dengan indeks 9, 18, 27 juga diklik). Pertama, kode saya di onBindViewHolder adalah:
if (newsItems.get(position).getBookmark() == 1) { holder.getToggleButtonBookmark().setChecked(true); }
Tapi kemudian saya menambahkan pernyataan Else
if (newsItems.get(position).getBookmark() == 1) { holder.getToggleButtonBookmark().setChecked(true); //else statement prevents auto toggling } else{ holder.getToggleButtonBookmark().setChecked(false); }
Dan masalahnya terpecahkan
sumber
oke ada banyak jawaban di sini saya akan memposting kode saya dan saya hanya akan menjelaskan apa yang saya lakukan ... itu mungkin membantu junior seperti saya: D.
1- Tujuan:
kami akan membuat daftar
RecyclerView
yang memilikiCheckBox
danRadioButton
, sesuatu seperti ini:2- Kelas Model
public class ModelClass { private String time; private boolean checked; private boolean free; private boolean paid; public TherapistScheduleModel(String time, boolean checked, boolean free, boolean paid) { this.time = time; this.checked = checked; this.free = free; this.paid = paid; } public boolean isFree() { return free; } public void setFree(boolean free) { this.free = free; } public boolean isPaid() { return paid; } public void setPaid(boolean paid) { this.paid = paid; } public String getTime() { return time; } public void setTime(String time) { this.time = time; } public boolean getChecked() { return checked; } public void setChecked(boolean checked) { this.checked= checked; } }
3-Adaptor Luar Biasa Saya
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> { private Context context; private ListAllListeners listAllListeners; private ArrayList<ModelClass> mDataList; public MyAdapter(Context context, ArrayList<ModelClass> mDataList, ListAllListeners listAllListeners) { this.mDataList = mDataList; this.listAllListeners = listAllListeners; this.context = context; } @NonNull @Override public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { LayoutInflater inflater = LayoutInflater.from(parent.getContext()); View view = inflater.inflate(R.layout.single_view, parent, false); return new MyViewHolder(view); } @Override public int getItemCount() { if (mDataList != null) return mDataList.size(); else return 0; } @Override public void onBindViewHolder(@NonNull final MyViewHolder holder, final int position) { //important to: //setOnCheckedChangeListener to 'null' holder.checkBoxTime.setOnCheckedChangeListener(null); holder.freeRB.setOnCheckedChangeListener(null); holder.paidRB.setOnCheckedChangeListener(null); //Check Box holder.checkBoxTime.setText(mDataList.get(holder.getAdapterPosition()).getTime()); //here we check if the item is checked or not from the model. if(mDataList.get(holder.getAdapterPosition()).getChecked()) holder.checkBoxTime.setChecked(true); else holder.checkBoxTime.setChecked(false); holder.checkBoxTime.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton compoundButton, boolean b) { if (b) { mDataList.get(holder.getAdapterPosition()).setChecked(true); listAllListeners.onItemCheck(holder.checkBoxTime.getText().toString(), holder.getAdapterPosition()); } else { mDataList.get(holder.getAdapterPosition()).setChecked(false); listAllListeners.onItemUncheck(holder.checkBoxTime.getText().toString(), holder.getAdapterPosition()); } } }); //Radio Buttons if(mDataList.get(holder.getAdapterPosition()).isFree()) holder.freeRB.setChecked(true); else holder.freeRB.setChecked(false); holder.freeRB.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton compoundButton, boolean b) { if (b) { mDataList.get(holder.getAdapterPosition()).setFree(true); listAllListeners.onFreeCheck(holder.freeRB.getText().toString(), holder.getAdapterPosition()); } else { mDataList.get(holder.getAdapterPosition()).setFree(false); listAllListeners.onFreeUncheck(holder.freeRB.getText().toString(), holder.getAdapterPosition()); } } }); //***and so on to paidRB*** }//end onBindViewHolder() public interface ListAllListeners { //here is a list of clicked listeners to use them as you want ;). //you can get a list of checked or unChecked of all void onItemCheck(String checkBoxName, int position); void onItemUncheck(String checkBoxName, int position); void onFreeCheck(String name, int pos); void onFreeUncheck(String name, int pos); void onPaidCheck(String name, int pos); void onPaidUncheck(String name, int pos); } class MyViewHolder extends RecyclerView.ViewHolder { CheckBox checkBoxTime; RadioButton freeRB, paidRB; MyViewHolder(View itemView) { super(itemView); checkBoxTime = itemView.findViewById(R.id.timeCheckBox); freeRB = itemView.findViewById(R.id.freeRadioBtn); paidRB = itemView.findViewById(R.id.paidRadioBtn); } }//end class MyViewHolder }//end class
3- Dalam Aktivitas Anda mendapatkan mereka sesuatu seperti ini:
myAdapter= new MyAdapter(getActivity().getApplicationContext(), mDataList, new MyAdapter.ListAllListeners() { @Override public void onItemCheck(String checkBoxName, int position) { Toast.makeText(getActivity(), "" + checkBoxName + " " + position, Toast.LENGTH_SHORT).show(); } @Override public void onItemUncheck(String checkBoxName, int position) { Toast.makeText(getActivity(), "" + checkBoxName + " " + position, Toast.LENGTH_SHORT).show(); } @Override public void onFreeCheck(String name, int position) { Toast.makeText(getActivity(), "" + name + " " + position, Toast.LENGTH_SHORT).show(); } @Override public void onFreeUncheck(String name, int position) { Toast.makeText(getActivity(), "" + name + " " + position, Toast.LENGTH_SHORT).show(); } @Override public void onPaidCheck(String name, int position) { Toast.makeText(getActivity(), "" + name + " " + position, Toast.LENGTH_SHORT).show(); } @Override public void onPaidUncheck(String name, int position) { Toast.makeText(getActivity(), "" + name + " " + position, Toast.LENGTH_SHORT).show(); } });
sumber
Saya memiliki masalah yang sama dalam daftar RecyclerView dengan sakelar, dan menyelesaikannya menggunakan jawaban @oguzhand, tetapi dengan kode ini di dalam checkChangeListener:
if (buttonView.isPressed()) { if (isChecked) { group.setSelected(true); } else { group.setSelected(false); } }else{ if (isChecked) { buttonView.setChecked(false); } else { buttonView.setChecked(true); } }
(Di mana 'grup' adalah entitas yang ingin saya pilih / batalkan pilihan)
sumber
kelas publik TagYourDiseaseAdapter extends RecyclerView.Adapter {private ReCyclerViewItemClickListener mRecyclerViewItemClickListener; Konteks pribadi mContext;
List<Datum> deviceList = Collections.emptyList(); /** * Initialize the values * * @param context : context reference * @param devices : data */ public TagYourDiseaseAdapter(Context context, List<Datum> devices, ReCyclerViewItemClickListener mreCyclerViewItemClickListener) { this.mContext = context; this.deviceList = devices; this.mRecyclerViewItemClickListener = mreCyclerViewItemClickListener; } /** * @param parent : parent ViewPgroup * @param viewType : viewType * @return ViewHolder * <p> * Inflate the Views * Create the each views and Hold for Reuse */ @Override public TagYourDiseaseAdapter.OrderHistoryViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_tag_disease, parent, false); TagYourDiseaseAdapter.OrderHistoryViewHolder myViewHolder = new TagYourDiseaseAdapter.OrderHistoryViewHolder(view); return myViewHolder; } /** * @param holder :view Holder * @param position : position of each Row * set the values to the views */ @Override public void onBindViewHolder(final TagYourDiseaseAdapter.OrderHistoryViewHolder holder, final int position) { Picasso.with(mContext).load(deviceList.get(position).getIconUrl()).into(holder.document); holder.name.setText(deviceList.get(position).getDiseaseName()); holder.radioButton.setOnCheckedChangeListener(null); holder.radioButton.setChecked(deviceList.get(position).isChecked()); //if true, your checkbox will be selected, else unselected //holder.radioButton.setChecked(objIncome.isSelected()); holder.radioButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { deviceList.get(position).setChecked(isChecked); } }); } @Override public int getItemCount() { return deviceList.size(); } /** * Create The view First Time and hold for reuse * View Holder for Create and Hold the view for ReUse the views instead of create again * Initialize the views */ public class OrderHistoryViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { ImageView document; TextView name; CheckBox radioButton; public OrderHistoryViewHolder(View itemView) { super(itemView); document = itemView.findViewById(R.id.img_tag); name = itemView.findViewById(R.id.text_tag_name); radioButton = itemView.findViewById(R.id.rdBtn_tag_disease); radioButton.setOnClickListener(this); //this.setIsRecyclable(false); } @Override public void onClick(View view) { mRecyclerViewItemClickListener.onItemClickListener(this.getAdapterPosition(), view); } }
}
sumber
ini akan terjadi ketika digunakan
setOnCheckedChangeListener
sebagai pengganti penggunaan itusetObClickListener
dan di dalamnya hanya melakukan pegangan mudah ini:if (list.get(position).isCheck()) { list.get(position).setCheck(false); } else { list.get(position).setCheck(true); }
semoga membantu seseorang jika demikian + pilih jawaban ini
sumber
Menambahkan setItemViewCacheSize (int size) ke recyclerview dan meneruskan ukuran daftar memecahkan masalah saya.
kode saya:
mrecyclerview.setItemViewCacheSize(mOrderList.size()); mBinding.mrecyclerview.setAdapter(mAdapter);
Sumber: https://stackoverflow.com/a/46951440/10459907
sumber
Hal ini karena berulang kali membuat tampilan, opsi terbaik adalah menghapus cache sebelum mengatur adaptor
recyclerview.setItemViewCacheSize(your array.size());
sumber
Contoh lengkap
kelas publik ChildAddressAdapter memperluas RecyclerView.Adapter <ChildAddressAdapter.CartViewHolder> {
private Activity context; private List<AddressDetail> addressDetailList; private int selectedPosition = -1; public ChildAddressAdapter(Activity context, List<AddressDetail> addressDetailList) { this.context = context; this.addressDetailList = addressDetailList; } @NonNull @Override public CartViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { LayoutInflater inflater = LayoutInflater.from(context); View myView = inflater.inflate(R.layout.address_layout, parent, false); return new CartViewHolder(myView); } @Override public void onBindViewHolder(@NonNull CartViewHolder holder, int position) { holder.adress_checkbox.setOnClickListener(view -> { selectedPosition = holder.getAdapterPosition(); notifyDataSetChanged(); }); if (selectedPosition==position){ holder.adress_checkbox.setChecked(true); } else { holder.adress_checkbox.setChecked(false); } } @Override public int getItemCount() { return addressDetailList.size(); } class CartViewHolder extends RecyclerView.ViewHolder { TextView address_text,address_tag; CheckBox adress_checkbox; CartViewHolder(View itemView) { super(itemView); address_text = itemView.findViewById(R.id.address_text); address_tag = itemView.findViewById(R.id.address_tag); adress_checkbox = itemView.findViewById(R.id.adress_checkbox); } }
}
sumber
Apa yang berhasil bagi saya adalah membatalkan listener di viewHolder saat tampilan akan didaur ulang (
onViewRecycled
):override fun onViewRecycled(holder: AttendeeViewHolder) { super.onViewRecycled(holder) holder.itemView.hasArrived.setOnCheckedChangeListener(null); holder.itemView.edit.setOnClickListener { null } }
sumber