-3

Now I am using RecyclerView with CheckBox. My Goal is get selected Checkbox list. Here My Problem is while I try to select any one Checkbox means it select two Checkbox at the same time. For example I am select in 0th position Checkbox but It automatically select 0th and 13th Both position Checkbox are getting selected.

There is no duplicate item adding while scrolling, Please understand clearly..

Here I have to attached my RecyclerView Adapter Class. Please any one help me..

Thanks in Advance.

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

    private ArrayList<ModuleViewModel> items =  new ArrayList<>();
    private OnItemCheckListener onItemClick;
    private Context mContext;

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(mContext).inflate(R.layout.item_modules_list, parent, false);

        return new MyViewHolder(view);
    }

    @Override
    public void onBindViewHolder(final MyViewHolder holder, final int position) {
        final ModuleViewModel currentItem = items.get(position);
        holder.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                    holder.checkbox.setChecked(
                            ! holder.checkbox.isChecked());
                    if ( holder.checkbox.isChecked()) {
                        onItemClick.onItemChecked(currentItem);
                    } else {
                        onItemClick.onItemUnchecked(currentItem);
                    }
            }
        });
    }

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

    public interface OnItemCheckListener {
        void onItemChecked(ModuleViewModel item);
        void onItemUnchecked(ModuleViewModel item);
    }

    public MyAdapter (Context context,ArrayList<ModuleViewModel> items, @NonNull OnItemCheckListener onItemCheckListener) {
        this.mContext = context;
        this.items = items;
        this.onItemClick = onItemCheckListener;
    }


    static class MyViewHolder extends RecyclerView.ViewHolder {
        CheckBox checkbox;
        View itemView;

        public MyViewHolder(View itemView) {
            super(itemView);
            this.itemView = itemView;
            checkbox = (CheckBox) itemView.findViewById(R.id.uiCkbModule);
            checkbox.setClickable(false);

        }

        public void setOnClickListener(View.OnClickListener onClickListener) {
            itemView.setOnClickListener(onClickListener);
        }
    }
}

This is My Adapter calling Code

mModuleListAdapter = new ModuleListAdapter(mContext, mModuleListModel, this);
 mRvModuleView.setAdapter(mModuleListAdapter);
Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
Raja
  • 2,775
  • 2
  • 19
  • 31
  • use Boolean field in model class and use that field for selection. – Subhash Prajapati Dec 30 '17 at 06:00
  • Possible duplicate of [Android RecyclerView Duplicate Item When Scrolling](https://stackoverflow.com/questions/37506978/android-recyclerview-duplicate-item-when-scrolling) – Dimitar Dec 30 '17 at 06:08
  • @user8, You guys are understand or not?... any where I am say **Duplicate Item When Scrolling**? then how you mark as duplicate? – Raja Dec 30 '17 at 06:10
  • 1
    I don't know the reason for why You guys are giving down vote for this.. any one can tell the reason. If you know the Solution give a solution. Please... – Raja Dec 30 '17 at 06:22

4 Answers4

2

Hello @Raja this is due to recyclerview behaviour. I have faced same issue so for solution I store the checkbox status in my model

public boolean status = false;

by default than onclicklistner update the status in the list view this will sove your issue.

@Override
public void onBindViewHolder(final MyViewHolder holder, final int position) {
    final Student student = items.get(position);
    holder.checkbox.setText(student.name + " :: " + student.department);
    holder.checkbox.setChecked(student.status);
    holder.checkbox.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (holder.checkbox.isChecked()) {
                onItemClick.onItemChecked(student);
            } else {
                onItemClick.onItemUnchecked(student);
            }
            student.status = holder.checkbox.isChecked();
            items.remove(position);
            items.add(position, student);
        }
    });
}

than its perfectly working for me..

Upendra Shah
  • 2,218
  • 17
  • 27
1

Could you please modify the following function, I believe ModelViewModel object will have some boolean variable to hold the state of check box.

@Override
    public void onBindViewHolder(final MyViewHolder holder, final int position) {
        final ModuleViewModel currentItem = items.get(position);
        holder.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                holder.checkbox.setChecked(! holder.checkbox.isChecked());
                if ( holder.checkbox.isChecked()) {
                    onItemClick.onItemChecked(currentItem);
                } else {
                    onItemClick.onItemUnchecked(currentItem);
                }
            }
        });

        if(!currentItem.isChecked) {
            holder.checkbox.setChecked(false);
        }else {
            holder.checkbox.setChecked(true);
        }
    }
lib4backer
  • 3,337
  • 3
  • 18
  • 16
1

This mostly happens because recyclerview recycles/reuses already created item views to reduce resource consumption.

There can be two approaches to handle this:

  1. Add a boolean variable isChecked in your ModuleViewModel model class and set it true/false for every list item. In this approach, the value of checked would be save for every model class in the class itself.

  2. Create an arraylist of booleans isChecked of same size of the items. Each element of isChecked arraylist will correspond to each item of the recyclerview list. You can then refer to the value of isChecked at that position to setChecked(true/false) your checkbox.

Shivam
  • 1,086
  • 7
  • 8
0

Try this take one boolean in your model like this isChecked and create getter and setter method for boolean variable

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

            if (isChecked) {
                items.get(position).isChecked=isChecked;
            } else {    
                items.get(position).isChecked=isChecked;
            }

        }
    });

than try this

holder.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                    if ( items.get(position).isChecked())) {
                        onItemClick.onItemChecked(currentItem);
                    } else {
                        onItemClick.onItemUnchecked(currentItem);
                    }
            }
        });
Goku
  • 9,102
  • 8
  • 50
  • 81
  • `this is not a solution Boss` can you explain why – Goku Dec 30 '17 at 06:13
  • Now i dont need `holder.setOnClickListener` this part of code. without any listeners and click event only I need. – Raja Dec 30 '17 at 06:15
  • than what about this condition `holder.checkbox.setChecked( ! holder.checkbox.isChecked());` can explain more what you want to achieve – Goku Dec 30 '17 at 06:16
  • Boss, That and all not a problem. Please understand. Who one use Boolean in unwanted place.. Its not good programming. – Raja Dec 30 '17 at 06:19