When recycleview scrolling parent activity button go disable

Viewed 272

I have a RecyclerView grid adapter contains checkboxes and a show button in parent activity.if we select checkbox parent activity show button to enable and if we unchecked checkbox show button will disable, this how my requirement, and its working fine, but when I scroll recycle view my show button to disable. When I scroll I am getting item.isChecked() is false..can anyone help me to achieve my requirement, pls explain

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

    try {
        final GridViewHolder viewHolder = (GridViewHolder) holder;

        final MyList item = items.get(position);

        viewHolder.myCheckBox.setTag(position);
        viewHolder.myCheckBox.setOnCheckedChangeListener(new 
   CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton compoundButton, 
    boolean b) {

                item.setChecked(b);

                if (item.isChecked())
                   Count++;
                else
                  Count--;

                if (Count > 0) {

                    ((MyActivity)context).showButton().setEnabled(true);

                } else {
                    ((MyActivity)context).showButton().setEnabled(false);
                }


        }
        });

        viewHolder.myCheckBox.setChecked(item.isChecked());


    } catch (Exception e) {
        e.printStackTrace();
    }
}

In my pojo list class i written two functions for identy checkbox return values

  boolean isChecked;
  public boolean isChecked() {
    return isChecked;
  }

public void setChecked(boolean isChecked) {
    this.isChecked = isChecked;
}

ViewHolder inner class in adapter

   public class GridViewHolder extends RecyclerView.ViewHolder {


    private CheckBox myCheckBox;


     public GridViewHolder(final View parent) {
        super(parent);

        myCheckBox = (CheckBox) parent.findViewById(myCheckBox);

       ((ProductListingActivity)context).showButton().setEnabled(false);

        parent.setOnClickListener(GridAdapterMy.this);
    }
  }
5 Answers

I faced the same issue as yours and this is how I fixed it.

@Override 
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
    try {
        final GridViewHolder viewHolder = (GridViewHolder) holder;

        viewHolder.myCheckBox.setTag(position);

        //add this two lines 
        viewHolder.myCheckBox.setOnCheckedChangeListener(null);
        viewHolder.myCheckBox.setChecked(items.get(position).isChecked());

        viewHolder.myCheckBox.setOnCheckedChangeListener(new 
            CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton compoundButton,boolean b) {


                items.get(position).setChecked(b);

                if (items.get(position).isChecked())
                   Count++;
                else
                  Count--;

                if (Count > 0) {
                   ((MyActivity)context).showButton().setEnabled(true);
                } else {
                   ((MyActivity)context).showButton().setEnabled(false);
                }}
        });

    } catch (Exception e) {
        e.printStackTrace();
    }
}

While scrolling onBindViewHolder called repetitively that's why state of checkbox changed automatically.so you have to save state of checkbox while scroll. have look.

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

       private final boolean[] mCheckedState;
       private final Context mContext;
       private CheckBox result;

    public MyListAdapter(Context context, int resource, int textViewResourceId, List<Object> objects) {
        super(context, resource, textViewResourceId, objects);
        mCheckedState = new boolean[objects.size()];
        mContext = context;
    }

  @Override 
 public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
   try {
    final GridViewHolder viewHolder = (GridViewHolder) holder;
    viewHolder.myCheckBox.setTag(position);

    //add this two lines 
    viewHolder.myCheckBox.setOnCheckedChangeListener(null);       
    result =  viewHolder.myCheckBox;
    if (result == null) {
        result = new CheckBox(mContext);
    }
    result.setChecked(mCheckedState[position]);
    viewHolder.myCheckBox.setOnCheckedChangeListener(new 
        CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton compoundButton,boolean b) {

             if(b){
                result.setChecked(mCheckedState[position]);
                  }
    });

} catch (Exception e) {
    e.printStackTrace();
}

} }

Happy coding!!

Create an extra variable in your POJO class:

public class DataItems {   

    int id, price, qty;
    String title;

    boolean isChecked; // create boolean variable like this

    public boolean isChecked() {
        return isChecked;
    }

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

}

then, add code like this in your adapter:

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

        // check here the state of your check from your arraylist of POJO
        if (dataItemsArrayList.get(position).isChecked) {
            holder.chkBox.setChecked(true);               
        } else {
            holder.chkBox.setChecked(false);
        }

        holder.tvTitle.setText(dataItemsArrayList.get(position).getTitle() + "");
        holder.tvPrice.setText(dataItemsArrayList.get(position).getPrice() + "");
        holder.tvQTY.setText(dataItemsArrayList.get(position).getQty() + "");
        holder.chkBox.setTag(position);

        holder.chkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                // save here the state of your check box when your select or unSelect the Checkbox
                if (isChecked) {

                    ((MainActivity)context).isChecked(true);
                    holder.chkBox.setChecked(true);
                    dataItemsArrayList.get(position).setChecked(true);


                } else {
                    ((MainActivity)context).isChecked(false);
                    holder.chkBox.setChecked(false);
                    dataItemsArrayList.get(position).setChecked(false);
                }

            }
        });

}

EDIT

Create a new Interface like below

public interface test {

    public void isChecked(boolean isChecked);
}

now implements in Your Activity like this

public class MainActivity extends AppCompatActivity implements test

than pass this Activity Context as parameter to Your Adapter

than add this code in Your activity

 @Override
    public void isChecked(boolean isChecked) {

        if(isChecked){
            // enable YOur Button here
        }else {
            // disable YOur Button here
        }
    }

try with this code

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
    try {
        final GridViewHolder viewHolder = (GridViewHolder) holder;

        final MyList item = items.get(position);

        viewHolder.myCheckBox.setTag(position);

        //add this two lines 
//        viewHolder.myCheckBox.setOnCheckedChangeListener(null);
        viewHolder.myCheckBox.setChecked(item.isChecked());
        viewHolder.myCheckBox.setTag(position);
        viewHolder.myCheckBox.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                int pos = Integer.parseInt(v.getTag().toString().trim());

                items.get(pos).setChecked(b);
                if(items.get(pos).isChecked()){
                    items.get(pos).setChecked(false);
                }else{
                    items.get(pos).setChecked(true);
                }

                if (items.get(pos).isChecked())
                   Count++;
                else
                  Count--;

                if (Count > 0) {
                   ((MyActivity)context).showButton().setEnabled(true);
                } else {
                   ((MyActivity)context).showButton().setEnabled(false);
                }
                });

    } catch (Exception e) {
        e.printStackTrace();
    }
}

Thanks everyone who helped me,i found my mistake,each time when i scroll,my setOnCheckedChangeListener was calling,thats why my button go disable,i added just one line "viewHolder.myCheckBox.setOnCheckedChangeListener(null);" its working perfectly..thank u somuch for urs advice and help

Related