1

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.

However I have a problem now. lets say i add 4 cardviews by pressing the fab, 1 2 3 and 4. When I tick the checkbox in cardview 3, cardview 4 disappears. But the checkbox in cardview 3 is ticked. When I go to click untick the checkbox in cardview 3, cardview 3 disappears. So essentially its deleting the wrong cardview instead of its own.

here is a screen record to show more explanation: https://streamable.com/vuq5t

And here following is my code

ProductAdapter

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(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

                                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();

            }
        });


        //checkbox ticked
        //here do holder.checkbox take your view holder checkbox

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

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


                Toast.makeText(create, "Done!", Toast.LENGTH_LONG).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);

        }

        public View getView() {
            return rootView;
        }

    }

}

create.java which is my mainactivity

public class create extends AppCompatActivity {



    //a list to store all the products
    List<Product> productList;

    //the recyclerview
    RecyclerView recyclerView;


    Product mProduct;
    private Map<String, String> numberItemValues = new HashMap<>();
    private Map<Integer, Integer> mSpinnerSelectedItem = new HashMap<Integer, Integer>();





    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.create);


        //opens csv
        InputStream inputStream = getResources().openRawResource(R.raw.shopitems);
         CSVFile csvFile = new CSVFile(inputStream);

       final List<String>  mSpinnerItems = csvFile.read();


        //getting the recyclerview from xml
        recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
        recyclerView.setHasFixedSize(true);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));

        //initializing the productlist
        productList = new ArrayList<>();
        productList.add(new Product(mSpinnerItems, "Test Edit Text",false, "Text String 2"));




      final ProductAdapter  adapter = new ProductAdapter(this, productList);

        //TODO FAB BUTTON
        FloatingActionButton floatingActionButton =
             findViewById(R.id.fab);


        floatingActionButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                productList.add(mProduct);
                if(adapter != null)
                    adapter.notifyDataSetChanged();
                //Handle the empty adapter here

            }
        });








        //setting adapter to recyclerview
        recyclerView.setAdapter(adapter);






    }



    private class CSVFile {
        InputStream inputStream;

        public CSVFile(InputStream inputStream) {
            this.inputStream = inputStream;
        }

        public List<String> read() {
            List<String> resultList = new ArrayList<String>();
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
            try {
                String line;
                while ((line = reader.readLine()) != null) {
                    String[] row = line.split(",");
                    //TODO I edited this part so that you'd add the values in our new hash map variable

                    numberItemValues.put(row[1], row[0]);

                    resultList.add(row[1]);
                }
            } catch (IOException e) {
                Log.e("Main", e.getMessage());
            } finally {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    Log.e("Main", e.getMessage());
                }
            }
            return resultList;
        }
    }



}

product.java

public class Product {

    private static String editText;
    private static Boolean checkBox;
    private static String textView5;

    public static List<String> spinnerItemsList = new ArrayList<String>();

    public Product(List spinner, String editText, Boolean checkBox, String textView5) {

        this.editText = editText;
        this.spinnerItemsList = spinner;
        this.checkBox = checkBox;
        this.textView5 = textView5;
    }
    public static String getEdittext () {
        return editText;
    }

    public static boolean getCheckbox () {
        return checkBox;
    }

    public static String getTextview () {
        return textView5;
    }
    public static List<String> getSpinnerItemsList () {
        return spinnerItemsList;
    }
}

ProductAdapter new - Suraj help

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(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

                                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){

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



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

                }
            });



        }

        public View getView() {
            return rootView;
        }

    }

}
aminography
  • 21,986
  • 13
  • 70
  • 74
Grand Skunk
  • 29
  • 18

5 Answers5

2

You are missing if(isChecked) in OnCheckedChangeListener You don't need to call notifyDataSetChanged(), use getAdapterPosition() instead of position.

  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){

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



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

                }
            });

        }

Add your code inside ProductViewHolder constructor

You need to create new product every time a new product added So:

 floatingActionButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                 mProduct= new Product() // **something like that which has some values, the thing is you need to create new product with new keyword**
                productList.add(mProduct);
                if(adapter != null)
                    adapter.notifyDataSetChanged();
                //Handle the empty adapter here

            }
        }); 

the thing is you need to create new product with new keyword

Suraj Vaishnav
  • 7,777
  • 4
  • 43
  • 46
  • Hello! That works however when I press the checkbox on all of them to delete, then theres nothing right, then I press the fab to add more cardviews but instead of having empty cardviews i have the cardviews tat i deleted? Like say I deleted a cardview which said potatochips on it, then i press fab to add a cardview, and the cardview with potatochips shows.. – Grand Skunk Oct 01 '18 at 05:49
  • and the checkbox is ticked on it . – Grand Skunk Oct 01 '18 at 05:50
1

Here you are deleting row in onBindViewHolder thats what it create a problem

Step 1:

Remove that onCheckedChangeLis from OnBind

Step 2

Do OnCheckedChangeLis in OnView Holder Like this

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.

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


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


        }
    });

    }

    public View getView() {
        return rootView;
    }

}

Hope this Solve your issue :)

Faiz Mir
  • 599
  • 5
  • 16
1

in your viewholder class add this line checkBox.setChecked(false);

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);
        checkBox.setChecked(false);
        rootView = itemView.findViewById(R.id.linearLayout);
}
Farrokh
  • 1,167
  • 1
  • 7
  • 18
1
Neeraj Bagra
  • 134
  • 7
0

I think this is checkbox selection issue in recyclerview.

Add this link in your onBindViewHolder()

holder.checkBox.setChecked(false) // OR set logic for checkbox selection

and

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

                    productList.remove(getAdapterPosition());
                    notifyItemRemoved(getAdapterPosition());
                    Toast.makeText(create, "Done!", Toast.LENGTH_LONG).show();
                  }

                }
            });

        }

Hope this may help you :)

Mitesh Vanaliya
  • 2,491
  • 24
  • 39