3

Below is the my code.

holder.followDiseaseCheckBox.setOnClickListener(new View.OnClickListener() {
        @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
        @Override
        public void onClick(View view) {

            if (holder.followDiseaseCheckBox.isChecked()) {

                holder.followDiseaseCheckBox.setChecked(true);

                checkBoxClicked++;
                holder.followDiseaseCheckBox.setChecked(true);
                // for Follow.
                if (isFollowOrUnFollow.equals("FOLLOW")) {

                    ((FollowActivity) context).diseaseListFromAdapter.add(String.valueOf(diseaseMap.get("id")));
                    ((FollowActivity) context).setFollowButton(true);

                }
                // for Unfollow.
                else if (isFollowOrUnFollow.equals("UN_FOLLOW")) {

                    ((FollowTwoActivity) context).unFollowedDiseaseListFromAdapter.add(String.valueOf(diseaseMap.get("id")));
                    ((FollowTwoActivity) context).setUnFollowDiseaseButton(true);
                }


            } else {

                holder.followDiseaseCheckBox.setChecked(false);

                checkBoxClicked--;
                holder.followDiseaseCheckBox.setChecked(false);
                // for Follow.
                if (isFollowOrUnFollow.equals("FOLLOW")) {
                    ((FollowActivity) context).diseaseListFromAdapter.remove(String.valueOf(diseaseMap.get("id")));
                }
                // for Unfollow.
                else if (isFollowOrUnFollow.equals("UN_FOLLOW")) {
                    ((FollowTwoActivity) context).unFollowedDiseaseListFromAdapter.remove(String.valueOf(diseaseMap.get("id")));
                }

                if (checkBoxClicked == 0) {

                    // for Follow.
                    if (isFollowOrUnFollow.equals("FOLLOW")) {
                        ((FollowActivity) context).setFollowButton(false);
                        ((FollowActivity) context).diseaseListFromAdapter.clear();
                    }
                    // for Unfollow.
                    else if (isFollowOrUnFollow.equals("UN_FOLLOW")) {

                        ((FollowTwoActivity) context).setUnFollowDiseaseButton(false);
                        ((FollowTwoActivity) context).unFollowedDiseaseListFromAdapter.clear();
                    }
                }
            }

        }
    });

Problem is When I select a checkBox including that checkBox some other checkBox in the RecyclerView gets checked. But when I check in adapter item got added properly but checkBox selection are getting duplicated.

Ex: If I checked first item checkBox and scroll down 16th items checkBox will also be checked. Unchecking that checkBox will uncheck the first item as well.

UltimateDevil
  • 2,807
  • 2
  • 18
  • 31
Ramu Hegde
  • 65
  • 1
  • 12

4 Answers4

12

You might have missing some concepts of recylerview. Fact is that recyclerview binds/ recycles same view after every 9 items. So inorder to avoid this just make use of setItemViewCacheSize() in your activity.

example:

contactListAdapter = new ContactsListAdapter(ContactActivity.this, contactArrayList);
        mRecyclerView.setItemViewCacheSize(contactArrayList.size());
        mRecyclerView.setAdapter(contactListAdapter);

public void setItemViewCacheSize(int size) Set the number of offscreen views to retain before adding them to the potentially shared recycled view pool. The offscreen view cache stays aware of changes in the attached adapter, allowing a LayoutManager to reuse those views unmodified without needing to return to the adapter to rebind them. Parameters: size - Number of views to cache offscreen before returning them to the general recycled view pool

Mohammed Farhan
  • 1,120
  • 8
  • 14
7

The recycler view recycles the view in OnBindViewHolder. So when items are clicked it gets reflected in some other positions. To create a global SparseBooleanArray to store the clicked position.

private final SparseBooleanArray array=new SparseBooleanArray();

Then inside final viewholder add the clickListener and onClick store the position of the clicked item.

public class ViewHolder extends RecyclerView.ViewHolder {
    public YOURVIEW view;
    public ViewHolder(View v) {
        super(v);
        view = (YOURVIEW) v.findViewById(R.id.YOURVIEWID);
        view.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                array.put(getAdapterPosition(),true);
                notifyDataSetChanged();
            }
        });
    }
}

And in inside OnBindViewHolder,

@Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
    if(array.get(position)){
        holder.followDiseaseCheckBox.setChecked(true);
    }else{
        holder.followDiseaseCheckBox.setChecked(false);
    }
}
Sharath kumar
  • 4,064
  • 1
  • 14
  • 20
  • Thanks @Anonymous, If click again, must be uncheck?, please check this : `view.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if(array.get(getAdapterPosition())){ array.put(getAdapterPosition(), false); }else{ array.put(getAdapterPosition(), true); } notifyDataSetChanged(); } });` – samaniego Apr 09 '19 at 17:19
3
public class CardViewDataAdapter extends RecyclerView.Adapter<CardViewDataAdapter.ViewHolder> {
    private List<Student> stList;
    public CardViewDataAdapter(List<Student> students) {
        this.stList = students;
    }

@Override
public CardViewDataAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
  // create a new view
    View itemLayoutView = LayoutInflater.from(parent.getContext()).inflate(
    R.layout.cardview_row, null);

  // create ViewHolder

  ViewHolder viewHolder = new ViewHolder(itemLayoutView);

  return viewHolder;
 }

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

  final int pos = position;

  viewHolder.tvName.setText(stList.get(position).getName());

  viewHolder.tvEmailId.setText(stList.get(position).getEmailId());

  viewHolder.chkSelected.setChecked(stList.get(position).isSelected());

  viewHolder.chkSelected.setTag(stList.get(position));


  viewHolder.chkSelected.setOnClickListener(new View.OnClickListener() {
    public void onClick(View v) {
    CheckBox cb = (CheckBox) v;
    Student contact = (Student) cb.getTag();

    contact.setSelected(cb.isChecked());
    stList.get(pos).setSelected(cb.isChecked());

    Toast.makeText(
      v.getContext(),
      "Clicked on Checkbox: " + cb.getText() + " is "
        + cb.isChecked(), Toast.LENGTH_LONG).show();
   }
  });

 }

 // Return the size arraylist
 @Override
 public int getItemCount() {
  return stList.size();
 }

 public static class ViewHolder extends RecyclerView.ViewHolder {

  public TextView tvName;
  public TextView tvEmailId;

  public CheckBox chkSelected;

  public Student singlestudent;

  public ViewHolder(View itemLayoutView) {
   super(itemLayoutView);

   tvName = (TextView) itemLayoutView.findViewById(R.id.tvName);

   tvEmailId = (TextView) itemLayoutView.findViewById(R.id.tvEmailId);
   chkSelected = (CheckBox) itemLayoutView.findViewById(R.id.chkSelected);

  }

 }

 // method to access in activity after updating selection
 public List<Student> getStudentist() {
  return stList;
 }
}

For more understanding about the selection of checkbox, follow this link

Mohammad Misbah
  • 870
  • 8
  • 19
  • @Shaido & alfakini - Relevant answer already posted, I don't answer the same solution, that why posted the reference link to more understanding. I think this will help to clear the concept. – Mohammad Misbah Oct 26 '17 at 11:45
  • 1
    @MohammadMisbah Links can break in the future, hence it is preferred to have the relevant information in the answer itself. If the information does not answer the question, maybe post it as a comment or add information to an existing answer. – Shaido Oct 26 '17 at 11:48
  • @ Shaido - Yes you are right, Sure I will update my answer. Thanx for review. – Mohammad Misbah Oct 26 '17 at 11:50
1
public class SuggestionListAdapter extends RecyclerView.Adapter<SuggestionListAdapter.SuggestionListViewHolder> {

private List<Suggestion> mSuggestionList;
private Context mContext;



public class SuggestionListViewHolder extends RecyclerView.ViewHolder{
    private CheckBox mCheckBox;
    private LinearLayout mParent;


    public SuggestionListViewHolder(View itemView) {
        super(itemView);
        mCheckBox = (CheckBox)itemView.findViewById(R.id.list_display_checkbox);
        mParent =(LinearLayout)itemView.findViewById(R.id.list_parentll);
    }
}

public SuggestionListAdapter(List<Suggestion> suggestionList, Context context) {
    this.mSuggestionList = suggestionList;
    this.mContext = context;
}

@Override
public SuggestionListViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View new_suggestion_list_view = LayoutInflater.from(parent.getContext()).inflate(R.layout.suggestion_list,parent,false);
    return new SuggestionListViewHolder(new_suggestion_list_view);
}
@Override
public void onBindViewHolder(final SuggestionListViewHolder holder, final int position) {

    final Suggestion suggestion = mSuggestionList.get(position);

    holder.mCheckBox.setText(suggestion.getCategory());
    holder.mCheckBox.setOnCheckedChangeListener(null);
    holder.mCheckBox.setSelected(suggestion.isSelected());
    holder.mCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            if(isChecked){
                suggestion.setSelected(true);
            }else {
                suggestion.setSelected(false);
            }
        }
    });
    holder.mCheckBox.setChecked(suggestion.isSelected());
}

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

}

have a look at this example i am sure you will found where you are doing mistake and you can solve your problem.

Deep Doshi
  • 77
  • 6