3

I have a RecyclerView which has a checkbox and textview.Numbers 10,20,30,40... till 500 should be shown in textview.The Checked checkboxes should add the numbers in the textview corresponding to the checkbox.For eg. if User checks the value 10 only, the textView would show 10. If user checks 20 as well, then TextView would show 30 ( 20 +10). If user uncheck 10 again, the TextView would show 20, and so on.When i click on checkbox some random checkbox is also checked.I tried one solution in stackoverflow. It did not work.I am stuck with this.Please help me..Here is my code:

RecyclerAdapter.java:

public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.RecyclerHolder>
    {

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

        @Override
        public void onBindViewHolder(@NonNull RecyclerHolder holder, final int position) {
            holder.number.setText(Integer.toString((Integer) alldata.get(position)));
            final String text=holder.number.getText().toString();


            holder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    Log.e("Checked","Checked");
                    if(checkeddata!=null)
                    {
                        if (checkeddata.size()==0)
                        {
                            checkeddata.add(text);

                        }
                        else {
                            if(checkeddata.contains(text))
                            {
                                checkeddata.remove(text);


                            }
                            else {
                                checkeddata.add(text);

                        }
                        }
                        Iterator iterator=checkeddata.iterator();
                        int sumnumber=0;
                        while (iterator.hasNext())
                        {
                            sumnumber= sumnumber+Integer.parseInt((String) iterator.next());
                        }
                        sum.setText(Integer.toString(sumnumber));
                    }


                }
            });


        }

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

        public class RecyclerHolder extends RecyclerView.ViewHolder
        {
            TextView number;
            CheckBox checkBox;
            public RecyclerHolder(View itemView) {
                super(itemView);
                number=itemView.findViewById(R.id.number);
                checkBox=itemView.findViewById(R.id.check);


            }
        }
    }
    public void data()
    {
        int g=1;
        for(int i=10;i<=500;i++)
        {
            if((i/10)==g)
            {
                g=g+1;
                alldata.add(i);
            }

        }
    }

recycler_lyt.xml:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto">
<TextView
    android:layout_width="150dp"
    android:layout_height="wrap_content"
    android:id="@+id/number"
    android:textSize="20sp"/>
    <CheckBox
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/check"
        android:checked="false"
        app:layout_constraintRight_toRightOf="parent"/>
</android.support.constraint.ConstraintLayout>
jobin
  • 1,489
  • 5
  • 27
  • 52
  • `TextView` in which you displaying sum is outside of `RecyclerView` or inside. if inside then which `TextView` you want to edit. Please clarify your question with picture or something. – Shubham Vala Jul 10 '18 at 08:23
  • Sorry i didnt mention.There is another textview below recyclerview.The sum is displayed there. – jobin Jul 10 '18 at 08:25
  • What is alldata? Does it contain a boolean field for the state of the checkbox? –  Jul 10 '18 at 08:27
  • [you can check this post](https://stackoverflow.com/questions/32427889/checkbox-in-recyclerview-keeps-on-checking-different-items) I think this is your answer. – Mustafa Kuloğlu Jul 10 '18 at 08:30
  • all data is the list of numbers from 10 to 500 in this order..10..20..30.. – jobin Jul 10 '18 at 08:31
  • 1
    [you can check this post](https://stackoverflow.com/questions/32427889/checkbox-in-recyclerview-keeps-on-checking-different-items) I think this is your answer. – Mustafa Kuloğlu Jul 10 '18 at 08:32
  • ^^^^ This question is indeed a duplicate of that post – Daniel C Jacobs Sep 28 '21 at 19:55

6 Answers6

3

It's normal. You are not setting your checkbox selected or not. You are selecting one and View holder keeps it selected

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

@Override
    public void onBindViewHolder(ViewHolder holder, final int position) {
        final Data data = myItems.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(data.isSelected());

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

    }

inside your onBindViewHolder you have to set your checkbox either checked or unchecked. if true, your checkbox will be selected, else unselected

holder.checkBox.setChecked(boolean);
MadLeo
  • 458
  • 1
  • 6
  • 24
2

You must store your checkbox state. You can do that in your model, for example:

class Model {
    String title;
    boolean checked;
}

Next you must pass List of Model items to your adapter and check/uncheck checkbox determined by your model.

if (listOfItems.get(position).checked) {
    viewHolder.checkbox.setChecked(true);
} else {
    viewHolder.checkbox.setChecked(false);
}

Remember that you always need to manage opposite state of views (like checkbox or visibility of view) in adapter.

MarcinR
  • 786
  • 1
  • 6
  • 16
0

Try This:

public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.RecyclerHolder>
{
private OnClickListener onClickListener;
private int sum =0;

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

    @Override
    public void onBindViewHolder(@NonNull RecyclerHolder holder, final int position) {
        holder.number.setText(Integer.toString((Integer) alldata.get(position)));
        final String text=holder.number.getText().toString();


        holder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if(isChecked){
                    sum += Integer.parseInt(holder.number.getText().toString());
                }else{
                    sum -= Integer.parseInt(holder.number.getText().toString());
                }
                if (onClickListener != null) {
                    onClickListener.onItemClick(sum);
                }
        });


    }

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

    public class RecyclerHolder extends RecyclerView.ViewHolder
    {
        TextView number;
        CheckBox checkBox;
        public RecyclerHolder(View itemView) {
            super(itemView);
            number=itemView.findViewById(R.id.number);
            checkBox=itemView.findViewById(R.id.check);


        }
    }

    public void setOnClickListener(OnClickListener onClickListener) {
        this.onClickListener = onClickListener;
    }

    public interface OnClickListener {
        void onItemClick(int sum);
    }
}

Now In activity use adapter instance like this:

private RecyclerAdapter adapter;
...
...
cardAdapter.setOnClickListener(new CardAdapter.OnClickListener() {
        @Override
        public void onItemClick(int sum) {
            txtSum.setText(String.valueOf(sum));
    });
Shubham Vala
  • 1,024
  • 7
  • 18
0

You need to have a field (like "isSelected") in your model class so that all the checked entries can be tracked.you can try following:

checkboxRecyclerView

Anu Bhalla
  • 422
  • 4
  • 11
0

Basically, RecyclerView recycles the view so you need a model to store the state of the checkbox.

public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.RecyclerHolder> {

    private List<Model> alldata = new ArrayList<>();

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

    @Override
    public void onBindViewHolder(@NonNull RecyclerHolder holder, final int position) {
        final Model model = alldata.get(position);

        holder.number.setText(String.valueOf(model.value));
        holder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                model.setChecked(isChecked); // Saves the state of the checkbox.

                if (checkeddata != null) {
                    if (checkeddata.size() == 0) {
                        checkeddata.add(text);

                    } else {
                        if (checkeddata.contains(model.getValue())) {
                            checkeddata.remove(model.getValue());


                        } else {
                            checkeddata.add(model.getValue());

                        }
                    }
                    Iterator iterator = checkeddata.iterator();
                    int sumnumber = 0;
                    while (iterator.hasNext()) {
                        sumnumber = sumnumber + Integer.parseInt((String) iterator.next());
                    }
                    sum.setText(Integer.toString(sumnumber));
                }
            }
        });
        holder.checkBox.setChecked(model.isChecked()); // Retrieves the state of your checkbox.
    }

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

    public class RecyclerHolder extends RecyclerView.ViewHolder {
        TextView number;
        CheckBox checkBox;

        public RecyclerHolder(View itemView) {
            super(itemView);
            number = itemView.findViewById(R.id.number);
            checkBox = itemView.findViewById(R.id.check);
        }
    }

    public void data() {
        int g = 1;
        for (int i = 10; i <= 500; i++) {
            if ((i / 10) == g) {
                g = g + 1;
                alldata.add(new Model(i));
            }
        }
    }

    private class Model {
        private int value;
        private boolean checked = false;

        Model(int value) {
            this.value = value;
        }

        public int getValue() {
            return value;
        }

        public boolean isChecked() {
            return checked;
        }

        public void setChecked(boolean checked) {
            this.checked = checked;
        }
    }
}
glagarto
  • 913
  • 8
  • 20
0

If you made the necessary changes to store the state of the checkbox, then:
in onBindViewHolder() after final String text=holder.number.getText().toString(); add this:

holder.checkBox.setOnCheckedChangeListener(null);
holder.checkBox.setChecked(-- stored value --);

and then add the listener for the checkbox.