How can I select only one checkbox in Recyclerview and notifydataset changed
this is the best code!
notice onBindViewHolder
public class SupportSchoolIdAdapter extends RecyclerView.Adapter<SupportSchoolIdAdapter.ViewHolder > {
private Context context;
ArrayList<SupportSchoolIdModel> supportSchoolIdModels;
private int selectedPosition = 0;
private ArrayList<Integer> selectCheck = new ArrayList<>();
public SupportSchoolIdAdapter (Context context, ArrayList<SupportSchoolIdModel> supportSchoolIdModels) {
this.context = context;
this.supportSchoolIdModels = supportSchoolIdModels;
//initilize selectCheck
for (int i = 0; i < supportSchoolIdModels.size(); i++) {
selectCheck.add(0);
}
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.support_school_item, parent, false);
return new ViewHolder(v);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
if (selectCheck.get(position) == 1) {
holder.checkbox.setChecked(true);
} else {
holder.checkbox.setChecked(false);
}
holder.checkbox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
for(int k=0; k<selectCheck.size(); k++) {
if(k==position) {
selectCheck.set(k,1);
} else {
selectCheck.set(k,0);
}
}
notifyDataSetChanged();
}
});
holder.checkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(isChecked==true){
//Do whatever you want to do with selected value
}
}
});
}
@Override
public int getItemCount() {
return supportSchoolIdModels== null? 0: supportSchoolIdModels.size();
}
class ViewHolder extends RecyclerView.ViewHolde {
CheckBox checkbox;
public ViewHolder(View v) {
super(v);
checkbox = (CheckBox) v.findViewById(R.id.checkbox);
}
}
}
Select one checkBox in item from recyclerView and deselect previously selected checkBox
Inside your Adapter
use this :
private int row_index;
@Override
public void onBindViewHolder(final Main_Page_Payment_Cash_Adapter.ViewHolder holder, final int position) {
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// checkbox.setChecked(true);
row_index = position;
notifyDataSetChanged();
}
});
if (row_index == position) {
// checkbox.setChecked(true);
} else {
// checkbox.setChecked(false);
}
}
I hope this is what you are looking for.
RecyclerView and notifyDataSetChanged LongClick mismatch
The problem is you're holding your checked state in the ViewHolder
itself - you're toggling its checkbox on and off depending on clicks, right?
The way a RecyclerView
works is that instead of having a ViewHolder
for every single item (like a ListView
does), it only creates a handful of them - enough for what's on screen and a few more for scrolling - and recycles those, using them to display different items.
That's what onBindViewHolder
is about - when it needs to display the item at position
, it hands you a ViewHolder
from its pool and says here you go, use that to display this item's details. This is where you do things like setting text, changing images, and setting things like checkbox state to reflect that particular item.
What you're doing is you're not storing the item's state anywhere, you're just setting the checkbox on the view holder. So if you check it, every item that happens to be displayed in that reusable holder object will have its box ticked. That's why you're seeing it pop up on other items - that checked state has nothing to do with the items themselves, just which view holder they all happen to use because of their position in the list.
So instead, you need to keep their checked state somewhere - it could be as simple as a boolean array that matches the length of your item list. Then you just set and get from that when binding your data (displaying it). Working with what you've got:
// all default to false
val itemChecked = BooleanArray(items.size)
override fun onBindViewHolder(holder: Holder, position: Int) {
...
// when displaying the data, refer to the checked state we're holding
holder.binding.checkbox.checked = itemChecked[position]
...
holder.itemView.setOnLongClickListener {
...
// when checking the box, update our checked state
// since we're calling notifyDataSetChanged, the item will be redisplayed
// and onBindViewHolder will be called again (which sets the checkbox)
itemChecked[position] = true
// notifyItemChanged(position) is better here btw, just refreshes this one
notifyDataSetChanged()
...
}
}
how to have single choice on checkbox in recyclerview?
you should define a state for each value of your list that you passed to your adapter.whit this state you can decide which checkbox must be checked or not. when a change occurs in items of adapter you must be notified with a listener in your activity and made a change to the state of each item of the list.
after that, just a simple adapter.notifyDataSetChanged() can make everything ok!
I try to make it clear with the sample code below :
Activity is something like this :
class MainActivity : AppCompatActivity(), Adapter.OnItemClick {
private val items = ArrayList<ListItems>()
private lateinit var adapter: Adapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setSupportActionBar(findViewById(R.id.toolbar))
items.add(ListItems(0, isChecked : false, checkable : true))
items.add(ListItems(1, isChecked : false, checkable : true))
items.add(ListItems(2, isChecked : false, checkable : true))
adapter = Adapter(items, this)
recyclerView.adapter = adapter
recyclerView.layoutManager = LinearLayoutManager(this)
}
override fun onItemClicked(position: Int, state: Boolean) {
Log.i("MainActivity", "onItemClicked: position :")
items.get(position).state = state
if (!state) {
for (item in items) {
item.checkable = true
}
} else {
for (x in 0 until items.size) {
items.get(x).checkable = x == position
}
}
adapter.notifyDataSetChanged()
}
and the adapter class :
class Adapter(val items: ArrayList, val onItemClick: OnItemClick) :
RecyclerView.Adapter<Adapter.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return ViewHolder(
LayoutInflater.from(parent.context).inflate(R.layout.item_adapter, parent, false)
)
}
override fun getItemCount(): Int {
return items.size
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val checkBox = holder.itemView.findViewById<CheckBox>(R.id.checkbox)
checkBox.isChecked = items.get(position).state
checkBox.isEnabled = items.get(position).editable
checkBox.setOnCheckedChangeListener(object :
CompoundButton.OnCheckedChangeListener {
override fun onCheckedChanged(p0: CompoundButton?, check:
Boolean) {
if (check) {
onItemClick.onItemClicked(position, true)
} else
onItemClick.onItemClicked(position, false)
}
})
}
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
}
interface OnItemClick {
fun onItemClicked(position: Int, state: Boolean)
}
}
Single selection in RecyclerView
The solution for the issue:
public class yourRecyclerViewAdapter extends RecyclerView.Adapter<yourRecyclerViewAdapter.yourViewHolder> {
private static CheckBox lastChecked = null;
private static int lastCheckedPos = 0;
public void onBindViewHolder(ViewHolder holder, final int position) {
holder.mTextView.setText(fonts.get(position).getName());
holder.checkBox.setChecked(fonts.get(position).isSelected());
holder.checkBox.setTag(new Integer(position));
//for default check in first item
if(position == 0 && fonts.get(0).isSelected() && holder.checkBox.isChecked())
{
lastChecked = holder.checkBox;
lastCheckedPos = 0;
}
holder.checkBox.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
CheckBox cb = (CheckBox)v;
int clickedPos = ((Integer)cb.getTag()).intValue();
if(cb.isChecked())
{
if(lastChecked != null)
{
lastChecked.setChecked(false);
fonts.get(lastCheckedPos).setSelected(false);
}
lastChecked = cb;
lastCheckedPos = clickedPos;
}
else
lastChecked = null;
fonts.get(clickedPos).setSelected(cb.isChecked);
}
});
}
}
Related Topics
How to Check If Data Is Inserted in Room Database
Remove Old Fragment from Fragment Manager
How to Set Space Between Listview Items in Android
How to Get Context in Android Mvvm Viewmodel
How to Access Data/Data Folder in Android Device
How to Keep a Bottom Nav Bar from Being Pushed Up on Keyboard Shown
Remove Green Border Around Android Application
How to Use Python to Execute Adb Commands
Android Edittext Text Control - How to Disable Possibility to Insert Gif from Google Keyboard
How to Go Back to Previous Fragment from Activity
Android Fastboot Waiting for Devices
How to Start an Activity from Background in Android 10
Access Ro.Serialno from Native in Android 8
Changing Cardview Shadow Color
Imageview of Png Doesn't Appear (Maybe It's Too Big)
How to Place an Imageview on Top of Another Imageview in Android
Java.Io.Ioexception: Permission Denied Cannot Create File
Install_Failed_User_Restricted:Android Studio Using Redmi 4 Device