【问题标题】:Getting error while deleting recyclerview items删除 recyclerview 项目时出错
【发布时间】:2018-02-27 20:32:54
【问题描述】:

我知道这是一个非常古老的问题,但即使参考了很多解决方案,也无法解决我的问题。实际上,我正在尝试删除 longclick 上的 recyclerview 项目,但出现以下错误。

顺便说一句,我在删除最后一项时没有收到任何错误,但是当我在删除除最后一项之外的任何其他项后尝试删除任何其他项时,我收到以下错误。

错误:

java.lang.ArrayIndexOutOfBoundsException: length=12; index=-1
                                                                    at java.util.ArrayList.remove(ArrayList.java:401)
                                                                    at community.infinity.message.MessageAdapter$1$1$1$1.run(MessageAdapter.java:219)
                                                                    at android.os.Handler.handleCallback(Handler.java:725)
                                                                    at android.os.Handler.dispatchMessage(Handler.java:92)
                                                                    at android.os.Looper.loop(Looper.java:137)
                                                                    at android.app.ActivityThread.main(ActivityThread.java:5041)
                                                                    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:793)
                                                                    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
                                                                    at dalvik.system.NativeStart.main(Native Method)

我的代码:

 @Override
 public void onBindViewHolder(ViewHolder holder, int position) {


 Message message = mMessages.get(position);
 holder.setMessage(message.getMessage());

 holder.msgContainer.setOnLongClickListener(view -> {
      int position = holder.getAdapterPosition();

 if (position != RecyclerView.NO_POSITION) {
 mMessages.remove(position);
 notifyItemRemoved(position);
 notifyItemRangeChanged(position, mMessages.size());
 }

        return false;
    });

 }

}
}

【问题讨论】:

  • 你好伙计,你提供的代码似乎仅限于我。但是查看错误日志,您似乎正在尝试访问超出数组范围的索引 -1。也许分享更多代码或再次校对您的代码?
  • 我们需要在您删除项目本身之前保存和恢复所选项目索引的代码
  • @AntonMakov 你的意思是onBindViewHolder的完整代码吗?
  • -1 可能是NO_POSITION 值。
  • @user8027365 是的,还有删除项目的代码

标签: android arraylist android-recyclerview


【解决方案1】:

这里有两个问题。

首先,您无需在拨打notifyItemRemoved() 后拨打notifyItemRangeChanged()。对notifyItemRemoved() 的调用将正确调整其余数据集。

其次,holder.getAdapterPosition() 有时会返回NO_POSITION(定义为-1)。当视图持有者知道它以前绑定到不再在适配器中的项目并且尚未重新绑定时,就会发生这种情况。由于您刚刚调用了notifyItemRemoved(holder.getAdapterPosition()),因此支架的适配器位置已被标记为无效,现在将返回为-1

如果您绝对必须调用notifyItemRangeChanged(),请重新编写您的代码,如下所示:

int position = holder.getAdapterPosition();

if (position != RecyclerView.NO_POSITION) {
    mMessages.remove(position);
    notifyItemRemoved(position);
    notifyItemRangeChanged(position, mMessages.size());
}

【讨论】:

  • 先生,您的回答对抑制错误很有帮助,但问题是某些项目在第一次尝试时没有被删除
  • 那么,有没有办法将 RecyclerView.NO_POSITION 转换为实际位置
【解决方案2】:

我个人曾经在适配器之外(在片段/活动中)有点击监听器

    public void onBindViewHolder(ViewHolder holder, int position)
    {
        //I'm saving here the position of the current item
        holder.rootView.setTag(position);

        //you set the listener functionality from the fragment/activity by sending 
        //to the constructor of your adapter
        holder.setLongClickListener(mListener);

        //init other fields of your item
        ...
    }

    // a function that will responsible to update the list without the deleted item
    public void setData(List<Data> data)
    {
         mData = data;
         notifyDataSetChanged();
    }
}

片段/活动

您的活动/片段应该实现接口长点击监听器

public class MyFragment extends Fragment implements View.LongClickListener
{
   ...

   public boolean onLongClick(View view) 
   {
         int selectedIndex = (int)view.getTag();
         mData.remove(selectedIndex);
         mAdapter.setData(mData);
         return true;
   }
}

别忘了用这个初始化适配器,它需要你的 onClickListener 实现。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-11
    • 1970-01-01
    • 2020-09-25
    • 2015-09-18
    相关资源
    最近更新 更多