Reputation: 2469
I want to make a list view in that an item contains a text and a checkbox and for checkbox listener I want to use onCheckedChange. I didn't understand the behavior of this listener, because when I check an item from the top of the list and then I scroll down and back to top, my checkbox state is unchecked but if I play more with the list it seems to work normally. I didn't understand if I use unproper the onCheckedChangeListener or it's a general problem. So here is a part of my code:
public View getView(int position, View convertView, ViewGroup parent) {
PickerItemDto item = items.get(position);
if (convertView == null) {
LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
convertView = mInflater.inflate(R.layout.picker_item, null);
ViewHolder viewHolder = new ViewHolder(convertView);
viewHolder.checkboxChange= new OnCheckboxChange();
viewHolder.cbSelectFriend.setOnCheckedChangeListener(viewHolder.checkboxChange);
convertView.setTag(viewHolder);
}
ViewHolder holder = (ViewHolder) convertView.getTag();
holder.tvName.setText(item.getName());
holder.cbSelectFriend.setChecked(item.isChecked());
holder.cbSelectFriend.setTag(item);}
private class OnCheckboxChange implements CompoundButton.OnCheckedChangeListener {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
CheckBox cb= (CheckBox) buttonView;
PickerItemDto item = (PickerItemDto) cb.getTag();
item.setChecked(isChecked);
}}
As far as I tested, the problem is because the onCheckboxChanged is called multiple times when I scoll the list and the isChecked value comes 'false' for elements that I already checked. I know that I can use onClickListener but I need onCheckBoxChange because I want to use a library for that only this listener is available.
Can anyone to explain my where I fault? Thanks
Upvotes: 0
Views: 1372
Reputation: 1894
onCheckboxChanged
called multiple times while scrolling because each time ListView reuse view you seting new checked value:
holder.cbSelectFriend.setChecked(item.isChecked());
You can fix it if you will create new OnCheckboxChange
each time in getView
method (now you create new OnCheckboxChange
only when convertView == null
):
if (convertView == null) {
LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
convertView = mInflater.inflate(R.layout.picker_item, null);
ViewHolder viewHolder = new ViewHolder(convertView);
convertView.setTag(viewHolder);
}
ViewHolder holder = (ViewHolder) convertView.getTag();
holder.cbSelectFriend.setOnCheckedChangeListener(new OnCheckboxChange());
holder.cbSelectFriend.setChecked(item.isChecked());
But it's not the optimal way. More simple and clean way is just use OnItemClickListener
Upvotes: 0
Reputation: 10299
Simple answer to your question is replace
holder.cbSelectFriend.setChecked(item.isChecked());
holder.cbSelectFriend.setTag(item);
with
holder.cbSelectFriend.setTag(item);
holder.cbSelectFriend.setChecked(item.isChecked());
Upvotes: 1