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 c
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;
}
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.
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
.
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);
}
});
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
}
}
});