Shailendra Kushwah
Shailendra Kushwah

Reputation: 415

How To handle Recyclerview state With checkboxes?

i am working with recyclerview . my recyclerview is populated from list and it has both states of checkbox after populating .but i have some problem when i checked or unchecked in specific position and after scrolling its still on their previous position. My code is shown below.

@Override

public void onBindViewHolder(final AttendanceHolder holder, final int position) {


    holder.statusCheckBox.setOnCheckedChangeListener(null);
    if(childrenListForAttendance.get(position).getStatus()==0) {
        holder.statusCheckBox.setTag(childrenListForAttendance.get(position));
        holder.childName.setText(childrenListForAttendance.get(position).getMchildName());
        holder.statusCheckBox.setChecked(childrenListForAttendance.get(position).isSelected());
    }
    else{
        holder.statusCheckBox.setTag(childrenListForAttendance.get(position));
        holder.childName.setText(childrenListForAttendance.get(position).getMchildName());
        holder.statusCheckBox.setChecked(false);
    }

    holder.statusCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            childrenListForAttendance.get(position).setIsSelected(isChecked);
        }
    });

}

    @Override
    public int getItemCount()

    {
        return childrenListForAttendance.size();
    }

How to handle this situation . thanks in advance.

Upvotes: 0

Views: 615

Answers (2)

Maciej Sikora
Maciej Sikora

Reputation: 20162

I do not see correcly setting checked:

holder.statusCheckBox.setChecked(true);

So you correcly uncheck, but when is true You never check checkbox.

Your code modify:

holder.statusCheckBox.setOnCheckedChangeListener(null);

//NOT_USED constant with value of status not used
if(childrenListForAttendance.get(position).getStatus()==NOT_USED){

  //code for not used checkbox
}
//is checked is constant with value of checked status
else if(childrenListForAttendance.get(position).getStatus()==IS_CHECKED) {

     holder.statusCheckBox.setChecked(true);
     //other code
}
//code for uncheck
else{

    holder.statusCheckBox.setChecked(false);
    //other code
}

holder.statusCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        childrenListForAttendance.get(position).setIsSelected(isChecked);
    }
});

Upvotes: 1

SaravInfern
SaravInfern

Reputation: 3388

The issue with CheckBox inside recyclerview is that the view gets recycled due to recycling of recyclerview and the value of Checkbox(check or uncheck) is not maintained

You may look at my example. You can do something like that:

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {

    private ArrayList<Model> myItems = new ArrayList<>();

    public MyAdapter (ArrayList<Model> getItems, Context context){
        try {
            mContext = context;
            myItems = getItems;
            }catch (Exception e){
            Log.e(FILE_NAME, "51: " + e.toString());
            e.printStackTrace();
        }
    }

    public class ViewHolder extends RecyclerView.ViewHolder {
        public TextView tView;
        public CheckBox cBox;

        public ViewHolder(View v) {
            super(v);
            tView = (TextView) v.findViewById(R.id.textView);
            cBox = (CheckBox) v.findViewById(R.id.checkBox);
        }
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, final int position) {
        final ObjectIncome objIncome = myItems.get(position);
        String content = "sample String";
        holder.tView.setText(content);

        //in some cases, it will prevent unwanted situations
        holder.cBox.setOnCheckedChangeListener(null);

        //if true, your checkbox will be selected, else unselected
        if(holder.statusCheckBox.get(position).getStatus()==IS_CHECKED) {

            holder.statusCheckBox.setChecked(true);

      }
      else{

            holder.statusCheckBox.setChecked(false);

       }
        holder.cBox.setChecked(Model.get(position).isSelected());

        holder.cBox.setOnCheckedChangeListener(new OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    //set your object's last status
                    Model.get(position).setSelected(isChecked);
            }
        });

    }
}

Upvotes: 1

Related Questions