Popa Andrei
Popa Andrei

Reputation: 2469

OnCheckedChangeListener in ListView

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

Answers (2)

gildor
gildor

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

Dhaval Patel
Dhaval Patel

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

Related Questions