Kiran Maheshwari
Kiran Maheshwari

Reputation: 148

How can I select only one checkbox in Recyclerview and notifydataset changed

In my code I have create recyclerview with check box and default one item selected already. now I want when select other item checkbox so deselect all other items mean one item select at time.

My Adapter code:

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

ArrayList<SupportSchoolIdModel> supportSchoolIdModels;
DataPref mDataPref;
String supportSchoolId;

public SupportSchoolIdAdapter(List<SupportSchoolIdModel> supportSchoolIdModels) {
    this.supportSchoolIdModels = new ArrayList<>(supportSchoolIdModels);
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    Context context = parent.getContext();
    mDataPref = DataPref.getInstance(context);
    supportSchoolId = mDataPref.getSupportSchoolId();
    View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.support_school_item, parent, false);
    return new ViewHolder(v);
}

@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
    final SupportSchoolIdModel event = supportSchoolIdModels.get(position);
    holder.bindData(supportSchoolIdModels.get(position));

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

    //if true, your checkbox will be selected, else unselected
    holder.checkbox.setChecked(supportSchoolIdModels.get(position).isSelected());

    holder.checkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            supportSchoolIdModels.get(holder.getAdapterPosition()).setSelected(isChecked);
        }
    });
    if (supportSchoolIdModels.get(position).getPkSchoolId().equalsIgnoreCase(supportSchoolId)) {
        holder.checkbox.setChecked(true);
    } else {
        holder.checkbox.setChecked(false);
    }
}
@Override
public int getItemCount() {
    return supportSchoolIdModels.size();
}
// Provide a reference to the views for each data item
// Complex data items may need more than one view per item, and
// you provide access to all the views for a data item in a view holder
public static class ViewHolder extends RecyclerView.ViewHolder {
    // each data item is just a string in this case
    private TextView schoolIdTxt;
    private TextView schoolNameTxt;
    private CheckBox checkbox;

    public ViewHolder(View v) {
        super(v);
        schoolIdTxt = (TextView) v.findViewById(R.id.schoolIdTxt);
        schoolNameTxt = (TextView) v.findViewById(R.id.schoolNameTxt);
        checkbox = (CheckBox) v.findViewById(R.id.checkbox);
    }
    public void bindData(SupportSchoolIdModel supportSchoolIdModel) {
        schoolIdTxt.setText(supportSchoolIdModel.getPkSchoolId());
        schoolNameTxt.setText(supportSchoolIdModel.getSchoolName());
    }
}
}

And Second problem is when I scroll recycle view why selected item unchecked. please help me.

Upvotes: 9

Views: 29494

Answers (6)

Hamidreza Shadabkia
Hamidreza Shadabkia

Reputation: 284

this is the best code! notice onBindViewHolder

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

private Context context;
ArrayList<SupportSchoolIdModel> supportSchoolIdModels;
private int selectedPosition = 0;
private ArrayList<Integer> selectCheck = new ArrayList<>();

public SupportSchoolIdAdapter (Context context, ArrayList<SupportSchoolIdModel> supportSchoolIdModels) {
    this.context = context;
    this.supportSchoolIdModels = supportSchoolIdModels;

//initilize selectCheck 
    for (int i = 0; i < supportSchoolIdModels.size(); i++) {
        selectCheck.add(0);
    }

}

@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
     View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.support_school_item, parent, false);
     return new ViewHolder(v);
}

@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {

    if (selectCheck.get(position) == 1) {
        holder.checkbox.setChecked(true);
    } else {
        holder.checkbox.setChecked(false);
    }

    holder.checkbox.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            for(int k=0; k<selectCheck.size(); k++) {
                if(k==position) {
                    selectCheck.set(k,1);
                } else {
                    selectCheck.set(k,0);
                }
            }
            notifyDataSetChanged();

        }
    });
    holder.checkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {

            if(isChecked==true){
                //Do whatever you want to do with selected value
            }
        }
    });

}

@Override
public int getItemCount() {
    return supportSchoolIdModels== null? 0: supportSchoolIdModels.size();
}

class ViewHolder extends RecyclerView.ViewHolde {

    CheckBox checkbox;

    public ViewHolder(View v) {
        super(v);
        checkbox = (CheckBox) v.findViewById(R.id.checkbox);          
    }

}

}

Upvotes: 8

Mudassar Ashraf
Mudassar Ashraf

Reputation: 972

Try this, complete example

public class ChildAddressAdapter extends RecyclerView.Adapter<ChildAddressAdapter.CartViewHolder> {

    private Activity context;
    private List<AddressDetail> addressDetailList;
    private int selectedPosition = -1;

    public ChildAddressAdapter(Activity context, List<AddressDetail> addressDetailList) {
        this.context = context;
        this.addressDetailList = addressDetailList;
    }

    @NonNull
    @Override
    public CartViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

        LayoutInflater inflater = LayoutInflater.from(context);
        View myView = inflater.inflate(R.layout.address_layout, parent, false);
        return new CartViewHolder(myView);
    }

    @Override
    public void onBindViewHolder(@NonNull CartViewHolder holder, int position) {

        holder.adress_checkbox.setOnClickListener(view -> {
            selectedPosition = holder.getAdapterPosition();
            notifyDataSetChanged();
        });

        if (selectedPosition==position){
            holder.adress_checkbox.setChecked(true);
        }
        else {
            holder.adress_checkbox.setChecked(false);
        }


    }

    @Override
    public int getItemCount() {
        return  addressDetailList.size();
    }

    class CartViewHolder extends RecyclerView.ViewHolder
    {
        TextView address_text,address_tag;
        CheckBox adress_checkbox;

        CartViewHolder(View itemView) {
            super(itemView);
            address_text = itemView.findViewById(R.id.address_text);
            address_tag = itemView.findViewById(R.id.address_tag);
            adress_checkbox = itemView.findViewById(R.id.adress_checkbox);
        }
    }
}

Upvotes: 2

an_droid_dev
an_droid_dev

Reputation: 1136

1- You can create a variable inside Adapter class that can be used to hold the selected position:

private int selectedPosition = -1;// no selection by default

2- Inside onBindViewHolder set Check State:

holder.checkBox.setChecked(selectedPosition == position);

3- Inside setOnCheckedChangeListener you must update position

this.selectedPosition = holder.getAdapterPosition();

4- Refresh adapter

adapter.notifyDatasetChanged();

EDIT

onBindViewHolder will be called for all positions,

So method setChecked will called for all CheckBoxes, This method have a boolean input.

In above example i write setChecked(selectedPosition == position). For more readable i can write:

if(selectedPosition == position){ 
   holder.checkBox.setChecked(true);
}
else{
   holder.checkBox.setChecked(false);
}

Upvotes: 26

Vishal Vaishnav
Vishal Vaishnav

Reputation: 3422

You can use below code; it will surely help you guys,

int selectedPosition=0;

 if (selectedPosition == position) {
            holder.itemView.setSelected(true); //using selector drawable


            GradientDrawable drawable = (GradientDrawable) holder.ll_portal.getBackground();
            drawable.setColor(getResources().getColor(R.color.darkorange));
            holder.tvPortalName.setTextColor(Color.parseColor("#FFFFFF"));


        } else {
            holder.itemView.setSelected(false);
            GradientDrawable drawable = (GradientDrawable) holder.ll_portal.getBackground();
            drawable.setColor(getResources().getColor(R.color.white));
            holder.tvPortalName.setTextColor(Color.parseColor("#000000"));
        }

        final int finalPosition = position;
        holder.ll_portal.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                totalDineInOrder= String.valueOf(gallaryModels.get(position).getDineInTotalOrder());
                totalPickupOrder= String.valueOf(gallaryModels.get(position).getPickupTotalOrder());
                selectedPosition= finalPosition;
                notifyDataSetChanged();
            }
        });

Upvotes: 2

Ashish Lamichhane
Ashish Lamichhane

Reputation: 1

public class MyTeamAdapter extends RecyclerView.Adapter { private Context context; private ArrayList myTeams;

private int prevSelection = -1;


public MyTeamAdapter(Context context, ArrayList<Team> myTeams) {
    this.context = context;
    this.myTeams = myTeams;
}

@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    return new ViewHolder(LayoutInflater.from(context).inflate(R.layout.item_my_team, parent, false));
}


@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, final int position) {
    final Team team = myTeams.get(position);
    ViewHolder viewHolder = (ViewHolder) holder;

    if (team.isTeamSelected()) {
        viewHolder.checkTeam.setChecked(true);
        prevSelection = position;
    } else {
        viewHolder.checkTeam.setChecked(false);
    }

    viewHolder.checkTeam.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
            if (b) {
                team.setTeamSelected(true);
                if (prevSelection >= 0) {
                    myTeams.get(prevSelection).setTeamSelected(false);
                    notifyItemChanged(prevSelection);
                }
                prevSelection = position;
            } else {
                team.setTeamSelected(false);
            }
        }
    });
}

@Override
public int getItemCount() {
    return myTeams.size();
}

public class ViewHolder extends RecyclerView.ViewHolder {
    RelativeLayout captainHolder, viceCaptainHolder;
    CheckBox checkTeam;
    TextView tvTeamName, tvCaptainName, tvCaptain, tvVCapName, tvVC, tvWcktKeeper, tvBatsMen, tvAllRounder, tvBowler;
    ImageView edtTeam, viewTeam, copyTeam;


    public ViewHolder(View itemView) {
        super(itemView);
        checkTeam = itemView.findViewById(R.id.cb_team);

        tvTeamName = itemView.findViewById(R.id.tv_team_name);

        captainHolder = itemView.findViewById(R.id.captain_holder);
        tvCaptainName = captainHolder.findViewById(R.id.tv_player_name);
        tvCaptain = captainHolder.findViewById(R.id.tv_player_type);

        viceCaptainHolder = itemView.findViewById(R.id.vc_holder);
        tvVCapName = viceCaptainHolder.findViewById(R.id.tv_player_name);
        tvVC = viceCaptainHolder.findViewById(R.id.tv_player_type);

        tvWcktKeeper = itemView.findViewById(R.id.tv_wckt_keeper);
        tvBatsMen = itemView.findViewById(R.id.tv_bats_men);
        tvAllRounder = itemView.findViewById(R.id.tv_all_rounder);
        tvBowler = itemView.findViewById(R.id.tv_baller);

        edtTeam = itemView.findViewById(R.id.edt_team);
        viewTeam = itemView.findViewById(R.id.view_team);
        copyTeam = itemView.findViewById(R.id.copy_team);

    }
}

}

Upvotes: 0

shalini
shalini

Reputation: 365

As you said, you are new to android first you will notice that your checkbox will have issues with recycler view.You selected some item in recycle view and after scrolling you will notice some other item is selected to solve this you need to follow this answer. or You need to create a boolean variable( to capture the state of checked checkbox for each item in recycler view)in your School Model class like this

 class SchoolModel{
    private boolean isChecked;
    public boolean isChecked(){
     return ischecked;}

    public void setIsChecked(boolean checked){
      isChecked = checked;
    }
   }

Second problem is to select only one checkbox and deselect rest of them for this you need write your logic(Check here for solution).And one major code change is to move your setOnCheckedChangeListener to view holder class because bindviewholder is called everytime you update your recyclerview and thus setting setOnCheckedChangeListener every time which is not correct.So you put this listener in view holder this will assign per checkbox listener only one time.

 checkBoxDeleteComment.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
               //your code
            }
        });

Upvotes: 0

Related Questions