0

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

Popa Andrei
  • 2,299
  • 21
  • 25
  • are you sure that `setChecked` is assigning the value you provide as parameter ? – Blackbelt May 17 '15 at 13:49
  • Yes. The problem is that when I check an item, in listener I set item.setChecked(true), but when I scroll the onCheckedChanged is called again for the same element that I checked but now isChecked param is false.. Probably this event is not designed for this kind of usage??? – Popa Andrei May 17 '15 at 14:12

2 Answers2

1

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());
Dhaval Patel
  • 10,119
  • 5
  • 43
  • 46
0

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

gildor
  • 1,789
  • 14
  • 19
  • It's the same behavior if I will create each time a new click listener. Also, I can't use the onItemClickListener because on item click I have another event – Popa Andrei May 17 '15 at 15:03
  • Are you try my example and it's not working yet? Can you show final code? If you can't use onItemClickListener you can use cbSelectFriend.setOnClickListener(). But you should set new onClickListener each time in getView method too. – gildor May 17 '15 at 17:22