简体   繁体   中英

Custom ListView always gets unchecked after scrolling over

I created an app is working with custom ListView . In the custom, ListView have Checkbox option. When I scroll up or down over the phone screen Checkbox got unchecked automatically. Do you have any solution on this case? Please help to solve this issue. Thanks!

customelist.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:app="http://schemas.android.com/apk/res-auto"
   xmlns:tools="http://schemas.android.com/tools"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:orientation="vertical"
   tools:context=".menu_list">

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <TextView
        android:id="@+id/textViewItemName"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_marginStart="10dp"
        android:layout_toEndOf="@+id/buttonBarcode"
        android:fontFamily="serif"
        android:text="Medium Text"
        android:textColor="@android:color/holo_red_dark"
        android:textSize="18sp"
        android:textStyle="bold" />


    <CheckBox
        android:id="@+id/checkboxList"
        android:layout_width="32dp"
        android:layout_height="30dp"
        android:layout_alignParentEnd="true"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:layout_marginEnd="30dp"
        android:background="@drawable/button_round_green"
        android:textAlignment="center"
        android:textColorHint="@android:color/holo_red_dark"
        android:textColorLink="@android:color/holo_red_dark" />

</RelativeLayout>
</RelativeLayout>

ListAdapter.java

public class listAdapter extends ArrayAdapter<String> {

private final Activity context;
private final String[] index_item;
private final String[] barcode_food;
private final String[] item_name;
private final String[] price_item;

//private TextView textView_name, textView_price;
//private Button button_index, button_barcode;
//private CheckBox checkBoxItem;

public listAdapter(Activity context, String[] index_item, String[] barcode_food, String[] item_name, String[] price_item) {
    super(context, R.layout.activity_menu_list, index_item);

    this.context = context;
    this.index_item = index_item;
    this.barcode_food = barcode_food;
    this.item_name = item_name;
    this.price_item = price_item;
}

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

    LayoutInflater inflater = context.getLayoutInflater();
    View rowView = inflater.inflate(R.layout.activity_menu_list,null,true);

    TextView textView_name = (TextView) rowView.findViewById(R.id.textViewItemName);

    final CheckBox checkBoxItem = (CheckBox) rowView.findViewById(R.id.checkboxList);

    textView_name.setText(item_name[position]);

    // Row View got click
    rowView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (checkBoxItem.isChecked()==true){
                checkBoxItem.setChecked(false);

            }
            else checkBoxItem.setChecked(true);
        }
    });



    // Return row view
    return rowView;
}

You need to modified like:

private final Activity context;
private final String[] index_item;
private final String[] barcode_food;
private final String[] item_name;
private final String[] price_item;
//add Array 
private final String[] selectedItems;

//private TextView textView_name, textView_price;
//private Button button_index, button_barcode;
//private CheckBox checkBoxItem;

public listAdapter(Activity context, String[] index_item, String[] barcode_food, String[] item_name, String[] price_item) {
    super(context, R.layout.activity_menu_list, index_item);

    this.context = context;
    this.index_item = index_item;
    this.barcode_food = barcode_food;
    this.item_name = item_name;
    this.price_item = price_item;

     // Loop to set all the items are unselected
     for(int i=0;i<index_item.lenght();i++){
        selectedItems[i] = false;
      }
}

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

    LayoutInflater inflater = context.getLayoutInflater();
    View rowView = inflater.inflate(R.layout.activity_menu_list,null,true);

    TextView textView_name = (TextView) rowView.findViewById(R.id.textViewItemName);

    final CheckBox checkBoxItem = (CheckBox) rowView.findViewById(R.id.checkboxList);

    textView_name.setText(item_name[position]);

if (selectedItems[position]){
                checkBoxItem.setChecked(true);

            }
            else checkBoxItem.setChecked(false);

    // Row View got click
    rowView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if(selectedItems[position]){
                selectedItems[position]= false;
            }else{
                 selectedItems[position]= true;
            }
            notifydatasetchanged
        }
    });



    // Return row view
    return rowView;
}

You have to Maintain Checkbox Array Selection Like below :

private final Boolean [] buttonCheckedState;

Your constructor Should like this:

public listAdapter(Activity context, String[] index_item, String[] barcode_food, String[] item_name, String[] price_item) {

super(context, R.layout.activity_menu_list, index_item);

this.context = context;
this.index_item = index_item;
this.barcode_food = barcode_food;
this.item_name = item_name;
this.price_item = price_item;
for(int i=0;i<index_item.lenght();i++){
    buttonCheckedState[i] = false;
  }

}

put this code in get View:

checkBoxItem.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                int getPosition = (Integer) buttonView.getTag();  // Here we get the position that we have set for the checkbox using setTag.
                buttonCheckedState[position]=buttonView.isChecked(); // Set the value of checkbox to maintain its state.
            }
        });


    checkBoxItem .setTag(position); // This line is important. 
   checkBoxItem.setChecked(buttonCheckedState[position]);

Something like this

    private final Activity context;
    private final String[] index_item;
    private final String[] barcode_food;
    private final String[] item_name;
    private final String[] price_item;
    private boolean[] checkboxes;

    //private TextView textView_name, textView_price;
    //private Button button_index, button_barcode;
    //private CheckBox checkBoxItem;

    public listAdapter(Activity context, String[] index_item, String[] barcode_food, String[] item_name, String[] price_item) {
        super(context, R.layout.activity_menu_list, index_item);

        this.context = context;
        this.index_item = index_item;
        this.barcode_food = barcode_food;
        this.item_name = item_name;
        this.price_item = price_item;
        this.checkboxes = new boolean[index_item.length];
        for(i = 0; i < checkboxes.length; i++)
             checkboxes[i] = false;
    }

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

        LayoutInflater inflater = context.getLayoutInflater();
        View rowView = inflater.inflate(R.layout.activity_menu_list,null,true);

        TextView textView_name = (TextView) rowView.findViewById(R.id.textViewItemName);

        final CheckBox checkBoxItem = (CheckBox) rowView.findViewById(R.id.checkboxList);

        textView_name.setText(item_name[position]);
        checkBoxItem.setChecked(checkboxes[position]);
        // Row View got click
        rowView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                 checkboxes[position] = !checkboxes[position];
                 checkBoxItem.setChecked(checkboxes[position]);
                /*if (checkBoxItem.isChecked()==true){
                    checkBoxItem.setChecked(false);

                }
                else checkBoxItem.setChecked(true);*/
            }
        });



        // Return row view
        return rowView;
    }

try this....i have modified your code

try this....



if(rowciew==null){   
ViewHolder viewholder; 
LayoutInflater inflater = context.getLayoutInflater();
View rowView = inflater.inflate(R.layout.activity_menu_list,null,true);

viewholder=new ViewHolder();

viewholder.textView_name = (TextView) rowView.findViewById(R.id.textViewItemName);

viewholder.checkBoxItem = (CheckBox)rowView.findViewById(R.id.checkboxList);

rowView.setTag(viewholder);
}else{
   viewholder=(ViewHolder) rowview.getTag();
}
  textView_name.setText(item_name[position]);

// Row View got click
rowView.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        if (viewholder.checkBoxItem.isChecked()==true){
            viewholder.checkBoxItem.setChecked(false);

        }
        else viewholder.checkBoxItem.setChecked(true);
    }
});

// Return row view
return rowView;

private class ViewHolder {
    TextView textView_name;
    CheckBox checkBoxItem;
}

}

Seems you are missing preserving the state of checkboxes. Each time an item is visible during scroll, Android re-renders it. Try like

@Override
public View getView(int position, View convertView, ViewGroup parent)
{
  //Inflate Single View
  View v= View.inflate(context, R.layout.row_item, null);

  //Bind Components
  TextView textView_name = (TextView) v.findViewById(R.id.textViewItemName);
  CheckBox checkBoxItem = (CheckBox) v.findViewById(R.id.checkboxList);

  //Populate Componengts
  textView_name.setText(item_name[position]);

  //Identify Checkbox clicks
  checkBoxItem.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
  {
    @Override
    public void onCheckedChanged(CompoundButton buttonView,boolean isChecked)
    {
      //Save checked data somewhere after checking isChecked()
    }
  });

  //Check checkbox state here
  if(checkBoxItem.isChecked())
  {
    checkBoxItem.setChecked(true);
  }
  else
  {
    checkBoxItem.setChecked(false);
  }

  //Return View
  return v;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM