问题
I have this code so far when the user presses the fab a cardview is added to the recyclerview. I also now made it so whenthe user presses a specific cardview, a dialog shows and when the user presses ok, that cardview gets deleted. but I have a problem
When there are 2 cardviews left in the recyclerview and i click to delete one of them I get this error:
10-01 09:20:45.473 28725-28725/com.app.supermarketaislefinder E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.IndexOutOfBoundsException: Invalid index 2, size is 2
at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:251)
at java.util.ArrayList.remove(ArrayList.java:399)
at com.app.supermarketaislefinder.ProductAdapter$2$2.onClick(ProductAdapter.java:123)
at android.support.v7.app.AlertController$ButtonHandler.handleMessage(AlertController.java:166)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4867)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1007)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:774)
at dalvik.system.NativeStart.main(Native Method)
Line 123 is at this lineproductList.remove(position);
What can I do about that?
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){
checkBox.setChecked(false);
spinner.setSelection(0);
productList.remove(getAdapterPosition());
notifyItemRemoved(getAdapterPosition());
Toast.makeText(create, "Done!", Toast.LENGTH_LONG).show();
}
}
});
}
public View getView() {
return rootView;
}
}
}
回答1:
The position of an item inside your list may change while you add and remove items from it. So, the position you assigned in your onClickListener
may not be the right one in the moment of the click.
Try with this:
public void onClick(DialogInterface dialog, int id) {
// ...
productList.remove(holder.getAdapterPosition());
notifyItemRemoved(holder.getAdapterPosition());
// ...
}
This way, you will be checking the position at the time of the click, not when you bind the ViewHolder
.
来源:https://stackoverflow.com/questions/52581804/dynamically-deleteing-cardviews-but-error