Grand Skunk
Grand Skunk

Reputation: 39

deleting all cardviews from recyclerview then adding new cardviews - adds same cardviews

When the user presses the FAB a cardview is added to the recyclerview. Inside each cardview is a checkbox. I want to make it so when the user ticks the checkbox in a specific cardview, that specific cardview is deleted.

(FYI each cardview has a spinner and checkbox and a textview and edittext)

I pressed the fab 4 times to add 4 cardviews to my screen. i then picked different things from the spinner to see what was happening. When I tick the checkbox, that cardviewdeletes. I ticked the checkbox for all of the cardviews until I had no cardviews left.

But then when I went to press the fab to add a new cardview, I noticed that that cardview has the same selected spinner value and the checkbox is already ticked..? For example say I firstly had a cardview which had 'potatoes' then I ticked that. Now therse nothing on my screen. then I press fab to add a cardview. Then I see that that cardview has 'potatoes' on it as wlel, and the checkbox is ticked..if that doesnt make sense, please ask for clarification

What to do?

ProductAdapter.java

public class ProductAdapter extends RecyclerView.Adapter<ProductAdapter.ProductViewHolder> {

    private Map<Integer, Integer> mSpinnerSelectedItem = new HashMap<Integer, Integer>();


//this context we will use to inflate the layout
    //Remove this..Please
    // CheckBox checkBox;

    //private Context mCtx;
    private SearchableSpinner spinner;

    //we are storing all the products in a list
    private List<Product> productList;

    private Activity create;

    public ProductAdapter(Activity activity) {
        create = activity;
    }


    //getting the context and product list with constructor
    public ProductAdapter(Activity activity, List<Product> productList) {
        // this.mCtx = mCtx;
        create = activity;
        this.productList = productList;
    }

    @Override
    public ProductViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        //inflating and returning our view holder
        LayoutInflater inflater = LayoutInflater.from(create);
        View view = inflater.inflate(R.layout.layout_products, null);
        return new ProductViewHolder(view);
    }

    @Override
    public void onBindViewHolder(final ProductViewHolder holder, final int position) {
        // //getting the product of the specified position


        ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<String>(create, R.layout.item_spinner_layout,
                Product.getSpinnerItemsList());
        spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

        holder.spinner.setAdapter(spinnerArrayAdapter);

        holder.spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int mPosition, long id) {
                mSpinnerSelectedItem.put(position, mPosition);

                TextView mTextView = view.findViewById(R.id.mSpinnerText);
           /* Toast.makeText(create, "Selected Item: " + mTextView.getText().toString(), Toast.LENGTH_LONG).show();
            Log.e("***************", "Selected Item: " + mTextView.getText().toString());*/


            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {

            }
        });


        //binding the data with the viewholder views
        if (mSpinnerSelectedItem.containsKey(position)) {
            holder.spinner.setSelection(mSpinnerSelectedItem.get(position));
        }


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


                AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(create);


                // set title
                alertDialogBuilder.setTitle("Delete Item");

                // set dialog message
                alertDialogBuilder
                        .setMessage("Are you sure you want to delete this item?")
                        .setCancelable(false)
                        .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int id) {
                                // if this button is clicked, close
                                // current activity


                                holder.checkBox.setChecked(false);
                                holder.spinner.setSelection(0);

                                productList.remove(position);
                                notifyItemRemoved(position);

                                Toast.makeText(create, "Item removed.", Toast.LENGTH_LONG).show();


                            }
                        })
                        .setNegativeButton("No", new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int id) {
                                // if this button is clicked, just close
                                // the dialog box and do nothing
                                dialog.cancel();
                            }
                        });

                // create alert dialog
                AlertDialog alertDialog = alertDialogBuilder.create();

                // show it
                alertDialog.show();

            }
        });





    }


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


    class ProductViewHolder extends RecyclerView.ViewHolder {

        SearchableSpinner spinner;
        EditText editText;
        TextView textView5;
        CheckBox checkBox;
        LinearLayout linearLayout;
        View rootView;


        public ProductViewHolder(View itemView) {
            super(itemView);

            spinner = itemView.findViewById(R.id.spinner);
            editText = itemView.findViewById(R.id.editText);
            textView5 = itemView.findViewById(R.id.textView5);
            checkBox = itemView.findViewById(R.id.checkBox);
            rootView = itemView.findViewById(R.id.linearLayout);


            checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    // makes the set disappear when checkbox is ticked.
                    if(isChecked){

                        holder.checkBox.setChecked(false);
                        holder.spinner.setSelection(0);

                        productList.remove(getAdapterPosition());
                        notifyItemRemoved(getAdapterPosition());



                        Toast.makeText(create, "Done!", Toast.LENGTH_LONG).show();
                    }

                }
            });



        }

        public View getView() {
            return rootView;
        }

    }

}

Upvotes: 1

Views: 180

Answers (1)

DAA
DAA

Reputation: 1386

RecyclerView recycles the ViewHolders for performance. This means, if the 'ViewHolder A' has 'option C' selected in your spinner, it won't be destroyed even if you remove the item from the list. When you add a new item to the list, your RecyclerView may reuse 'ViewHolder A' for that item, and the selection remains the same it was for your previous item (before it was deleted).

To avoid this, update your UI manually when you add a new item to the list using the findViewByPosition method of your LayoutManager.

Example:

// FAB button onClick method:
public void onClick(View v) {
    // Add item to RecyclerView list

    int itemPosition = myRecyclerViewAdapter.itemList.indexOf(newItem);
    ProductViewHolder vh = ((ProductViewHolder)recyclerView.getLayoutManager().findViewByPosition(itemPosition));

    // Here, set everything to the default values (unchecked checkbox, etc)
}

If you want to keep all RecyclerView related code in your Adapter (which I encourage you to do), you could update the ViewHolder UI to the default values after you delete your item (instead of when adding one), so your ViewHolder is fresh and ready for the next item.

Example (use this solution better):

// Your positive button when deleting item onClick:
public void onClick(DialogInterface dialog, int id) {

    productList.remove(position);
    notifyItemRemoved(position);

    // Set spinner to default
    // Set checkbox to unchecked

    Toast.makeText(create, "Item removed.", Toast.LENGTH_LONG).show();
}

Upvotes: 2

Related Questions