问题
I'm trying to show an AlertDialog
in my ViewHolder
class and after clicking on accept button I'm getting the Model item with getAdapterPosition
from a list of items but in Fabric Crashlytics I have 13 crashes because of ArrayIndexOutOfBoundsException
which says length is 12 but the index requested is -1 and the crash is for getPaymentMode
in this part of code
class ViewHolder extends RecyclerView.ViewHolder {
TextView time, capacity, description;
View button;
ImageView avatar;
ViewHolder(View v) {
super(v);
time = v.findViewById(R.id.reserve_times_time);
capacity = v.findViewById(R.id.reserve_times_capacity);
button = v.findViewById(R.id.button);
description = v.findViewById(R.id.reserve_times_description);
avatar = v.findViewById(R.id.avatar);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
alertDialogBuilder.setView(R.layout.layout_dialog);
alertDialogBuilder.setPositiveButton("accept", null);
alertDialogBuilder.setNegativeButton("cancel", null);
final AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
alertDialog.getButton(DialogInterface.BUTTON_POSITIVE).setTextSize(TypedValue.COMPLEX_UNIT_PX, context.getResources().getDimension(R.dimen.dialog_button_text_size));
alertDialog.getButton(DialogInterface.BUTTON_NEGATIVE).setTextSize(TypedValue.COMPLEX_UNIT_PX, context.getResources().getDimension(R.dimen.dialog_button_text_size));
alertDialog.getButton(DialogInterface.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
alertDialog.dismiss();
getPaymentMode(arrayList.get(getAdapterPosition()), button);
}
});
}
});
}
in RecyclerView
source code getAdapterPosition
returns -1 when owner RecyclerView
is null and that will happen if activity is closed but how this can be happened? when AlertDialog
is displaying user can't close activity!
回答1:
According to the docs, getAdapterPosition()
will return NO_POSITION
(aka -1) if your view holder has already been recycled.
The adapter position of the item if it still exists in the adapter. NO_POSITION if item has been removed from the adapter, notifyDataSetChanged() has been called after the last layout pass or the ViewHolder has already been recycled.
My guess is that by the time you're clicking on your dialog button, your view holder has already been recycled. Try to store the position right when your onClick()
method begins and then use it when you need it, something like:
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final int position = getAdapterPosition()
//Your code here
alertDialog.getButton(DialogInterface.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
alertDialog.dismiss();
getPaymentMode(arrayList.get(position), button);
}
});
}
});
来源:https://stackoverflow.com/questions/48880846/getadapterposition-returns-1-in-viewholder-class