开发者

CheckBox changes value twice

开发者 https://www.devze.com 2023-01-19 11:09 出处:网络
I have an Android ListView whose items have a checkbox. The checkbox is checked by default. Once unchecked it should be removed from the list.

I have an Android ListView whose items have a checkbox.

The checkbox is checked by default. Once unchecked it should be removed from the list.

The problem is that onCheckedChanged is being fired twice: when I tap the checkbox to uncheck it (with isChecked false) and after I remove the item (with isChecked true).

This is the relevant code of my ArrayAdapte开发者_如何学Gor:

public View getView(final int position, View convertView, ViewGroup parent) {
    ViewHolder holder;
    if (convertView == null) {
        convertView = mInflater.inflate(R.layout.item, parent, false);
        holder = new ViewHolder();
        holder.check = (CheckBox) convertView.findViewById(R.id.check);
        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }
    final Object item = this.getItem(position);
    holder.check.setOnCheckedChangeListener(new CheckBox.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            if (!isChecked) {
                remove(item); // This somehow calls onCheckedChanged again
            }
        }
    });
    return convertView;
}

What am I doing wrong?


I had a similar issue and just resolved it properly without having to avoid using the intended OnCheckedChangeListener.

Problem Code

holder.someCheckBox.setChecked(false);
holder.someCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
    @Override
    public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
       ...
    }
});

Note I set the check status before I set the listener, this was to prevent the listener from firing on creation.

But, the listener started firing the on-check event exactly twice only after the adapter was forced to be re-created or through use of notifyDataSetChanged.

Solution

Clear the listener before setting the check state, even during creation here.

holder.someCheckBox.setOnCheckedChangeListener(null);
holder.someCheckBox.setChecked(false);
holder.someCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
    @Override
    public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
       ...
    }
});

Now any residual listeners will not be fired when setting the initial value of the checkbox.


I encountered the same problem, it seems to be an Android bug this twice execution of onCheckChanged method.

My solution: implement onClickListener, instead of onCheckedChangedListener.

Something like this:

private final class CheckUpdateListener implements OnClickListener {

    private Group parent;
    private boolean isChecked;

    private CheckUpdateListener(Group parent) {

        this.parent = parent;

    }

    @Override
    public void onClick(View box) {
        this.isChecked = !parent.isChecked();

        parent.setChecked(isChecked);

        notifyDataSetChanged();

    }

}


I encounter the same issue.

After some research i found out that there is a similar behaviour in RadioGroup for the setCheckChangeListener.

Tagging messes things up, seems like a bug.

My workaround was setting the tag to null at the end of the listener It worked for me.

private OnCheckedChangeListener checkBoxitemClickListener = new OnCheckedChangeListener() {

    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {


        if(isChecked)
        {               
            //do smth
        }else
        {
            //do smth
        }   

        buttonView.setTag(null);                        
    }
};

If you need to update your ListView after, don't forget to call "notifyDataSetChanged" on your adapter.

Cheers

0

精彩评论

暂无评论...
验证码 换一张
取 消