1

before you flag this as duplicate i have read a lot of posts about this but haven't found an answer to my solution.

I have a RecyclerView being populated with some data from database. Each RecyclerView item has a CheckBox originally with android:visibility="gone". Then i press the button and each item's CheckBox of the RecyclerView should appear. As i scroll down to see if all CheckBoxes appeared the top CheckBoxes are hidden.

My code:

private void setupButtonCallbacks() {
        modify.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                for (int position=0; position<recyclerView.getChildCount();position++){
                    recyclerView.getChildAt(position).findViewById(R.id.deleteCheckCartItem).setVisibility(View.VISIBLE);
                    recyclerView.getChildAt(position).findViewById(R.id.deleteCheckCartItem).setTag(position);
                }
                adapter.notifyDataSetChanged();
            }
        });
    }

The Adapter:

public class CartAdapter extends RecyclerView.Adapter<CartAdapter.CartViewHolder>{

    List<CartList> cartItems;
    Context context;
    CartList lista;

    public CartAdapter(List<CartList> cartItems, Context context){
        this.cartItems = cartItems;
        this.context = context;
    }

    @Override
    public CartViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.cart_row_item, parent, false);
        CartViewHolder pvh = new CartViewHolder(view);
        return pvh;
    }

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

        holder.cartProductName.setText(cartItems.get(position).getName());
        holder.cartProductprice.setText(cartItems.get(position).getPrice());
        holder.pref1.setText(cartItems.get(position).getPreferation1());
        holder.pref2.setText(cartItems.get(position).getPreferation2());
        holder.pref3.setText(cartItems.get(position).getPreferation3());
        holder.pref4.setText(cartItems.get(position).getPreferation4());
        holder.quantity.setText(cartItems.get(position).getQuantity());
        Ion.with(holder.cartProductImage).placeholder(R.mipmap.placeholder).error(R.mipmap.placeholder).load(cartItems.get(position).getImage());
        final CartList list = cartItems.get(position);
        holder.checkBox.setTag(list);
        holder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (holder.checkBox.isChecked()){
                    Toast.makeText(context, "Item Checked is " + cartItems.get(position).getName(), Toast.LENGTH_SHORT).show();
                }
            }
        });

    }

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

    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
    }

    public static class CartViewHolder extends RecyclerView.ViewHolder {
        CardView cardView;
        CheckBox checkBox;
        TextView cartProductName, cartProductprice, pref1, pref2, pref3, pref4, quantity;
        ImageView cartProductImage;
        LinearLayout linearLayout;

        CartViewHolder(View itemView) {
            super(itemView);
            cardView = (CardView)itemView.findViewById(R.id.card_view);
            linearLayout = (LinearLayout)itemView.findViewById(R.id.rootLinear);
            checkBox = (CheckBox)itemView.findViewById(R.id.deleteCheckCartItem);
            cartProductName = (TextView)itemView.findViewById(R.id.product_name_cart);
            cartProductprice = (TextView)itemView.findViewById(R.id.product_price_cart);
            pref1 = (TextView)itemView.findViewById(R.id.pref1_text_cart);
            pref2 = (TextView)itemView.findViewById(R.id.pref2_text_cart);
            pref3 = (TextView)itemView.findViewById(R.id.pref3_text_cart);
            pref4 = (TextView)itemView.findViewById(R.id.pref4_text_cart);
            quantity = (TextView)itemView.findViewById(R.id.quantity_text_cart);
            cartProductImage = (ImageView)itemView.findViewById(R.id.product_image_cart);

        }
    }

}

The Layout:

<android.support.v7.widget.CardView
        android:id="@+id/card_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="15dp">

        <LinearLayout
            android:id="@+id/rootLinear"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="?android:attr/selectableItemBackground"
            android:clickable="true"
            android:focusable="true"
            android:orientation="vertical">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="horizontal">

                <CheckBox
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:padding="15dp"
                    android:visibility="gone"
                    android:focusable="false"
                    android:layout_gravity="center_vertical"
                    android:id="@+id/deleteCheckCartItem" />

The Result is:

The first 2 items are having normal behavior and

First

and the last two are not having CheckBoxes visible

Second

Update As I was suggested i tried to keep track of the positions visible like this:

private void setupButtonCallbacks() {
        modify.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                for (int position = 0; position < recyclerView.getChildCount(); position++) {
                    recyclerView.getChildAt(position).findViewById(R.id.deleteCheckCartItem).setVisibility(View.VISIBLE);
                    cartItems.get(position).setCheckboxIsVisible(true);
                    adapter.notifyDataSetChanged();
                }
                actionMode = startSupportActionMode(actionModeCallback);
                actionMode.setTitle(getString(R.string.selected_modifiable_items));
            }
        });
    }

And the adapter:

@Override
public void onBindViewHolder(final CartViewHolder holder, final int position) {
    holder.cartProductName.setText(cartItems.get(position).getName());
    holder.cartProductprice.setText(cartItems.get(position).getPrice());
    holder.pref1.setText(cartItems.get(position).getPreferation1());
    holder.pref2.setText(cartItems.get(position).getPreferation2());
    holder.pref3.setText(cartItems.get(position).getPreferation3());
    holder.pref4.setText(cartItems.get(position).getPreferation4());
    holder.quantity.setText(cartItems.get(position).getQuantity());
    Ion.with(holder.cartProductImage).placeholder(R.mipmap.placeholder).error(R.mipmap.placeholder).load(cartItems.get(position).getImage());
    lista = cartItems.get(position);
    holder.checkBox.setVisibility(lista.isCheckboxIsVisible()?View.VISIBLE:View.GONE);
    holder.checkBox.setChecked(lista.isChecked());
    holder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            if (holder.checkBox.isChecked()) {
                //Toast.makeText(context, "Item Checked is " + cartItems.get(position).getName(), Toast.LENGTH_SHORT).show();
                boolean condition = cartItems.get(position).isChecked();
                condition = isChecked;
            }


        }
    });

}

It only makes it for the first 3 items on the list and then none of them is selected...

Any ideas? Thanks in advance!!!

Kostas Drak
  • 3,222
  • 6
  • 28
  • 60

3 Answers3

4

Your CartList cartItems needs to keep track of the visibility and checkbox state.

class CartList
...
    boolean checkboxIsVisible=false;//todo add setters and getters
    boolean isChecked=false;//todo add setters and getters

then in onBindViewHolder()

 final CartList list = cartItems.get(position);
        holder.checkBox.setVisible(list.checkboxIsVisible?View.VISIBLE:View.GONE);
        holder.checkBox.setChecked(list.isChecked)

checked

...
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                ...
                cartItems.get(position).isChecked=isChecked;
            }

modify visibility

...
@Override
public void onClick(View v) {
...//Some logic here that sets visibility to true or false
    recyclerView.getChildAt(position).checkboxIsVisible=true;
...
    adapter.notifyDataSetChanged();
}
TouchBoarder
  • 6,422
  • 2
  • 52
  • 60
2

The views of the RecyclerView are recycled, as the name says. So if the user checks the checkbox on one item, the same checkbox view might appear for another item that wasn't checked, still in it's checked state.

You have to to checkBox.setChecked(true/false) in every onBindViewHolder()

which means you have to keep track for which item the checkbox was checked (ArrayList of checked items, HashMap with items and boolean values, whatever).

fweigl
  • 21,278
  • 20
  • 114
  • 205
  • my problemm is not that the checkbox is checked or unchecked. the problemm is that when i scroll the checkbox visibility changes – Kostas Drak Dec 13 '15 at 19:52
  • @helldawg13 Same principle applies to that. You have to setVisibility on every onBindViewHolder, which you currently dont. – fweigl Dec 13 '15 at 20:03
1

I encountered the same problem in my project . What I did was set the Invisible field on both OnBindViewHolder and at adapter setOnClickListner

mAdapterForChooser.setClickListener(new AdapterForChooser.ClickListener() {

                @Override
                public void onClick(View v, int pos) {



                    RelativeLayout rl = (RelativeLayout) v.findViewById(R.id.selectedBg);

                    if (!mGiantChooserModels.get(pos).isSelected()) {

                        rl.setVisibility(View.VISIBLE);

                    } else {
                        rl.setVisibility(View.INVISIBLE);

                }
            });

And my holder is

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



    //Main Trick

    if(mGiantChooserModels.get(position).isSelected())
        holder.selector.setVisibility(View.VISIBLE);
    else
        holder.selector.setVisibility(View.INVISIBLE);

    holder.itemView.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub

            clickListener.onClick(v, position);
        }
    });
}
1shubhamjoshi1
  • 546
  • 7
  • 16