Home » Android » Checkbox auto call onCheckedChange when listview scroll?

Checkbox auto call onCheckedChange when listview scroll?

Posted by: admin February 23, 2018 Leave a comment

Questions:

I have a problem with listview which list item contain a checkbox. When i check a box and scroll list, checkbox sometime auto call oncheckedchange and value of checkbox is changed!

Or, when my list has more than 9 or 10 item, then when i checked at item 1, item 8 or 9 is checked???

Anyone can tell me what do i fix this bug?

Thanks in advance!

list_item.xml

<ImageView
    android:layout_alignParentLeft="true"
    android:layout_width="36dip"
    android:layout_height="36dip"
    android:layout_centerVertical="true"
    android:scaleType="fitCenter"
    android:id="@+id/image_view"
    android:src="@drawable/icon" />

<TextView android:layout_toRightOf="@id/image_view"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:paddingLeft="5dip"
    android:id="@+id/text_view"
    android:lines="1"
    android:textSize="20sp"
    android:textColor="@color/white" />

<TextView android:layout_toRightOf="@id/image_view"
    android:layout_below="@id/text_view"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:paddingLeft="5dip"
    android:id="@+id/text_view2"
    android:textSize="14sp"
    android:lines="1"
    android:textColor="@color/white" />          

and here is adapter view:

    public View getView(int position, View convertView, ViewGroup parent) {
        Log.e(TAG, "getView");
        ViewHolder mViewHolder;
        if (convertView == null) {
            Log.e(TAG, "Inflater is inflating...");
            convertView = mInflater.inflate(R.layout.custom_list_app, null);
            mViewHolder = new ViewHolder();
            mViewHolder.checkbox = (CheckBox) convertView.findViewById(R.id.checkbox);
            mViewHolder.remove = convertView.findViewById(R.id.music_info);
            convertView.setTag(mViewHolder);
        } else {
            mViewHolder = (ViewHolder) convertView.getTag();
            Log.e(TAG, "Position: " + position + " CheckBox: " + mViewHolder.checkbox.isChecked());
        }   
        mViewHolder.checkbox.setOnCheckedChangeListener(new OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(CompoundButton cb, boolean flag) {
                // TODO Auto-generated method stub
                if (flag) {
                    Log.d(TAG, "Checkbox checked");
                } else {
                    Log.d(TAG, "Checkbox un-checked");
                }
            }
        });


        return convertView;
    }
Answers:

The ListView recycles the view classes: you will need to explicitly set whether or not the CheckBox is checked in the getView class. So add a check like

/**
*    Ensure no other setOnCheckedChangeListener is attached before you manually
*    change its state.
*/
mViewHolder.checkbox.setOnCheckedChangeListener(null);
if(shouldBeChecked) mViewHolder.checkbox.setChecked(true);
else mViewHolder.checkbox.setChecked(false);

before you call setOnCheckedChangeListener.

Questions:
Answers:
holder.cBox.setOnCheckedChangeListener(null);
holder.cBox.setChecked(list.get(position).isChecked());
holder.tvName.setText(item.getName());

holder.cBox.setOnCheckedChangeListener(new OnCheckedChangeListener()
{
    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
    {
        if (isChecked)
        {
            list.get(position).setChecked(true);
        }
        else
        {
            list.get(position).setChecked(false);
        }
    }
});

In the list, the item have an attribute to set whether the item is checked or not. You can use this to set you item whether checked, and first you should set the

cBox.setOnCheckedChangeListener(null);
cBox.setChecked(list.get(position).isChecked());

Then set the real new OnCheckedChangeListener()

I hope my answer is useful for you and those who look at this page or have trouble dealing with listviews that have item checkboxes.

Questions:
Answers:

I am not sure if this is a neat way. But the below code solved my problem. Even in the below code, the setOnCheckChangeListener() was getting called (read falsely triggered) on scrolling of the list. The task was to maintain a list of items that have been selected by the user. So when there is a trigger, I first refer my list and only add an item if it was not already present in the list, else I ignore the callback.

@Override
public View getView(final int position, View convertView, final ViewGroup parent) {


    MenuViewHolder menuViewHolder = null;
    MenuView item = getItem(position);


    LayoutInflater inflater = ((Activity) context).getLayoutInflater();

    convertView = inflater.inflate(R.layout.food_menu_list_layout, null);

    TextView textView = ((TextView) convertView.findViewById(R.id.menu_item_entry));
    TextView price = (TextView) convertView.findViewById(R.id.price);
    CheckBox ordered = (CheckBox) convertView.findViewById(R.id.checkBox);

    menuViewHolder = new MenuViewHolder(textView, price, ordered);

    menuViewHolder.dishName.setText(menuViewList.get(position).getItemname());
    menuViewHolder.price.setText("$" + menuViewList.get(position).getPrice());
    menuViewHolder.ordered.setChecked(menuViewList.get(position).isSelected());

    menuViewHolder.ordered.setOnCheckedChangeListener(null);


    menuViewHolder.ordered.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {

            MenuView checkedItem = menuViewList.get(position);
            if (buttonView.isChecked()) {

                //add item only if not already added
                if (!checkedItem.isSelected()) {
                    MainActivity.menuViews.add(checkedItem);
                    checkedItem.setSelected(buttonView.isChecked());
                }       


            } else {

                //remove only if already added
                if (checkedItem.isSelected()){
                    MainActivity.menuViews.remove(checkedItem);
                    checkedItem.setSelected(buttonView.isChecked());
                }                    
            }

            ((MainActivity) context).displayCurrentSelectionAmt();
        }
    });


return convertView;

}

Questions:
Answers:

Most of these are way too involved (but they do work). All you are trying to do is stop the .setChecked event from firing if the view is being loaded and setting the checked status. So, set a local class variable isLoading, set it to true at the beginning of getView and set it to false at the end of getView. Then in the click listener, check isLoading

boolean isLoading;
public View getView(int position, View convertView, ViewGroup parent){
    isLoading = true;

    ...do your initialization here

    isLoading = false;
    return convertView;
}
checkview.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton pckView, boolean pisChecked) {
            if(! isLoading) {
                ...do your things when the check is actually clicked
            }
        }
    });

Questions:
Answers:

The OnClickListener is worked for me with the same problem and i can send a data to another activity

holder.cks.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                final boolean isChecked = holder.cks.isChecked();
                if (isChecked) {
                    System.out.println(position + "Checked");
                    holder.cks.setChecked(true);
                    positionArray.set(position, true);
                    DATA2="1";



                } else {
                    System.out.println(position + "unChecked");
                    holder.cks.setChecked(false);
                    positionArray.set(position, false);

                    DATA2 = "0";

                }
                DATA1=String.valueOf(position+1);

                DATA3=map.get(COL5);
                DATA4=map.get(COL6);
                DATA5=map.get(COL7);



                Intent intent = new Intent(activity, updatelicaldata.class);
                intent.putExtra("message1", DATA1);
                intent.putExtra("message2", DATA2);
                intent.putExtra("message3", DATA3);
                intent.putExtra("message4", DATA4);
                intent.putExtra("message5", DATA5);
                System.out.println("ACTIVITY IS START");

                activity.startActivity(intent);

            }
            });