【问题标题】:getAdapterPosition returns -1 in ViewHolder classgetAdapterPosition 在 ViewHolder 类中返回 -1
【发布时间】:2018-02-20 08:34:42
【问题描述】:

我试图在我的ViewHolder 类中显示一个AlertDialog,在单击接受按钮后,我从项目列表中获取带有getAdapterPosition 的模型项目,但在 Fabric Crashlytics 中我有 13 次崩溃,因为ArrayIndexOutOfBoundsException 表示长度为 12,但请求的索引为 -1,并且在这部分代码中,getPaymentMode 崩溃

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

RecyclerView 源代码getAdapterPosition 中,当所有者RecyclerView 为空时返回-1,如果活动已关闭,则会发生这种情况,但这是怎么发生的呢?当AlertDialog 显示用户无法关闭活动时!

【问题讨论】:

  • 发布ViewHolder代码
  • 问题已编辑@josh_gom3z
  • 显示你的 onbind 方法和你设置适配器的位置
  • @Amir_P getAdapterPosition() 是你点击的项目的位置吗?
  • 没错@Umair

标签: java android android-recyclerview


【解决方案1】:

根据docs,如果您的视图持有者已被回收,getAdapterPosition() 将返回NO_POSITION(又名-1)。

项目的适配器位置(如果它仍然存在于适配器中)。 NO_POSITION 如果项目已从适配器中删除,则在最后一次布局传递后已调用 notifyDataSetChanged() 或 ViewHolder 已被回收。

我的猜测是,当您单击对话框按钮时,您的视图持有者已经被回收了。尝试在您的 onClick() 方法开始时存储位置,然后在需要时使用它,例如:

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

【讨论】:

  • 此解决方案还有其他副作用吗?项目有 20K+ 用户,恐怕这会导致其他问题
  • 这只是基于我能看到的代码的有根据的猜测。在您的生产应用程序中使用它之前一定要测试它,就像您在 Stack Overflow 上看到的任何其他答案一样
  • 使用当前代码,我无法重现错误,所以很难确定,但我会测试一下,谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-30
  • 2018-01-10
  • 2023-03-03
  • 2015-11-09
  • 1970-01-01
相关资源
最近更新 更多