Android:Recycler视图项快速单击它会使应用程序崩溃

时间:2017-10-04 13:53:38

标签: android android-recyclerview

我已经搜索了很多我所做的是创建了一个项目列表简单的数字和复选框哪个是选中和取消选中,所以当我快速点击快速列表它崩溃 并生成 ArrayIndexOutOfBound异常

所以我不知道我做错了什么

这是我的代码

适配器类

  class SingleListItemHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

private TextView mItemDate, mFontSizeCategory;
    private ImageView isChecked, isTrack, isUnChecked;
    private int fontSize = 13;
SingleListItemHolder(View v) {
    super(v);
    mFontSizeCategory = (TextView) v.findViewById(R.id.tv_font_size_category);
    mItemDate = (TextView) v.findViewById(R.id.tv_recycler_view_list_header);
    isChecked = (ImageView) v.findViewById(R.id.iv_recycler_view_list_item_selected);
    isUnChecked = (ImageView) v.findViewById(R.id.iv_recycler_view_list_item_unselected);
    isTrack = (ImageView) v.findViewById(R.id.iv_track);
    v.setOnClickListener(this);
    this.setIsRecyclable(false);
}

@Override
public void onClick(View v) {
    mSingleItemListModels.get(pos).setSelected(false);
    notifyItemChanged(pos, mSingleItemListModels.get(pos));
    pos = getAdapterPosition();
    mSingleItemListModels.get(pos).setSelected(true);
    notifyItemChanged(pos, mSingleItemListModels.get(pos));
}

4 个答案:

答案 0 :(得分:4)

pos = getAdapterPosition();

向上移动

mSingleItemListModels.get(pos).setSelected(false);

答案 1 :(得分:3)

在使用 pos = getAdapterPosition();

之前,您必须先获取该项目
@Override
public void onClick(View v) {

    pos = getAdapterPosition();


    mSingleItemListModels.get(pos).setSelected(false);
    notifyItemChanged(pos, mSingleItemListModels.get(pos));
    mSingleItemListModels.get(pos).setSelected(true);
    notifyItemChanged(pos, mSingleItemListModels.get(pos));
}

答案 2 :(得分:3)

  

你在getAdapterPosition()中获得-1位置,因为当你快点击它时,它会抛出-1位置

您可以查看

if (pos != RecyclerView.NO_POSITION) {
//Do your setting part
}

更改此代码

@Override
public void onClick(View v) {
    mSingleItemListModels.get(pos).setSelected(false);
    notifyItemChanged(pos, mSingleItemListModels.get(pos));
    pos = getAdapterPosition();
    mSingleItemListModels.get(pos).setSelected(true);
    notifyItemChanged(pos, mSingleItemListModels.get(pos));
}

代码

@Override
public void onClick(View v) {
    mSingleItemListModels.get(pos).setSelected(false);
    notifyItemChanged(pos, mSingleItemListModels.get(pos));
    pos = getAdapterPosition();
     if (pos != RecyclerView.NO_POSITION) {
        mSingleItemListModels.get(pos).setSelected(true);
        notifyItemChanged(pos, mSingleItemListModels.get(pos));
     }
}

答案 3 :(得分:2)

您滥用getAdapterPosition。使用它来获取当前显示项目的索引并不是一个好主意。更糟糕的是,如果您调用了适配器更改(使用-1执行了两次),它也可能返回notifyItemChanged

查看文档here

  

请注意,如果您调用了notifyDataSetChanged(),则在下一个布局传递之前,此方法的返回值将为NO_POSITION。

NO_POSITION的值为-1。因此,不应将ClickListener实施到RecyclerView.ViewHolder,而应在onBindViewHolder中实施,因为您拥有当前索引。

在这里使用

 @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
       // the position will be the correct one
       // but don't store the position in a class field 
       // since it may change during scrolling
    }