Duplication in Checkbox selection in RecyclerView

戏子无情 提交于 2019-12-02 01:06:54

问题


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.


回答1:


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



回答2:


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




回答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




回答4:


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.



来源:https://stackoverflow.com/questions/46951014/duplication-in-checkbox-selection-in-recyclerview

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!