Android 回收视图';s已删除的行仍然获得单击事件?

Android 回收视图';s已删除的行仍然获得单击事件?,android,android-recyclerview,Android,Android Recyclerview,我有一个显示项目列表的RecyclerView。每行的ViewHolder包含一个删除按钮,用于删除该行。如果我删除最后一行并快速点击消失的行,我可能会崩溃我的应用程序,因为第二次点击事件会传递到删除的行。我很惊讶android提供了第二个事件。在我尝试向我的ViewHolder子类添加类似booleanisdeleted的内容之前,我想知道:在这种情况下,我是不是做错了什么 class MyAdapter extends RecyclerView.Adapter<MyViewHolder

我有一个显示项目列表的
RecyclerView
。每行的
ViewHolder
包含一个删除按钮,用于删除该行。如果我删除最后一行并快速点击消失的行,我可能会崩溃我的应用程序,因为第二次点击事件会传递到删除的行。我很惊讶android提供了第二个事件。在我尝试向我的
ViewHolder
子类添加类似
booleanisdeleted
的内容之前,我想知道:在这种情况下,我是不是做错了什么

class MyAdapter extends RecyclerView.Adapter<MyViewHolder> 
                implements ItemTouchHelperAdapter {

    List<Segment> segments;
    MyAdapter(List<Segment> objs) {
        this.segments = objs;
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        LinearLayout v = (LinearLayout) LayoutInflater.from(parent.getContext())
                .inflate(R.layout.segment_edit_row, parent, false);
        MyViewHolder vh = new MyViewHolder(v);
        return vh;
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        Segment seg = segments.get(position);
        holder.textView.setText(seg.getTitle());

        holder.dragHandle.setOnTouchListener((v, event) -> {
            if (MotionEventCompat.getActionMasked(event) ==
                    MotionEvent.ACTION_DOWN) {
                onStartDrag(holder);
            }
            return false;
        });
        holder.deleteButton.setOnClickListener(v -> {                
            segments.remove(position);
            notifyItemRemoved(position);
        });

        View.OnClickListener editExerciseListener = v -> {                
            Segment segment = segments.get(position);
            startEditSegmentActivity(segment, position);
        };

        holder.textView.setOnClickListener(editExerciseListener);
        holder.arrow.setOnClickListener(editExerciseListener);
    }
类MyAdapter扩展了RecyclerView.Adapter 实现ItemTouchHelperAdapter{ 列出各段; MyAdapter(列表objs){ this.segments=objs; } @凌驾 公共MyViewHolder onCreateViewHolder(视图组父级,int-viewType){ LinearLayout v=(LinearLayout)LayoutFlater.from(parent.getContext()) .充气(R.layout.segment\u edit\u row,parent,false); MyViewHolder vh=新的MyViewHolder(v); 返回vh; } @凌驾 公共无效onBindViewHolder(MyViewHolder,int位置){ 段seg=段get(位置); holder.textView.setText(seg.getTitle()); holder.dragHandle.setOnTouchListener((v,事件)->{ if(MotionEventCompat.getActionMasked(事件)== MotionEvent.ACTION(下一步){ 启动(支架); } 返回false; }); holder.deleteButton.setOnClickListener(v->{ 段。删除(位置); 已移除(位置)的项目; }); View.OnClickListener editExerciseListener=v->{ 段=段。获取(位置); 启动IT部门活动(部门、职位); }; holder.textView.setOnClickListener(EditExecuteStener); holder.arrow.setOnClickListener(editExerciseListener); } 首先运行
deleteButton
处理程序,然后运行
editExerciseListener
,此时
位置已超出范围

更新

有几个人建议我调用
notifydatasetchange
。如果您可以通过调用
notifyitemsremoved
来描述更改,Android文档特别建议不要这样做


这些文档是否有误?

每次执行删除操作时,您都必须重新加载recyclerview: 可以通过添加以下行来执行此操作:

yourAdapter.notifyDataSetChanged();

每次执行删除操作时都必须重新加载recyclerview: 可以通过添加以下行来执行此操作:

yourAdapter.notifyDataSetChanged();
将代码更新为:

    View.OnClickListener editExerciseListener = v -> {  

            if(position >= segments.size()){
              //index not exists
            }else{
              // index exists
            Segment segment = segments.get(position);
            startEditSegmentActivity(segment, position);
            }              

        };
将代码更新为:

    View.OnClickListener editExerciseListener = v -> {  

            if(position >= segments.size()){
              //index not exists
            }else{
              // index exists
            Segment segment = segments.get(position);
            startEditSegmentActivity(segment, position);
            }              

        };

第一次呼叫
notifyItemRemoved(位置);


然后调用
segments.remove(位置);
第一次调用
notifyItemRemoved(位置);


然后调用segments.remove(position);

我不久前遇到过类似的情况。当我单击正在删除并正在进行删除动画的recyclerview项时,该应用程序崩溃(不到一秒钟)。在这种情况下,你的应用程序易受潜在崩溃影响的持续时间非常短

我所做的:

当应用程序崩溃时,我记录了position(holder.getAdapterPosition())的值。令人惊讶的是,每次崩溃发生时,该值都是-1。最终,我编写了一个自定义版本的notifyItemRemoved。如下所示:

private void notifyItemRemovedModified(int pos_removed){
    if(pos_removed!=-1){
        // your list is your list
        yourList.remove(pos_removed);
        notifyItemRemoved(pos_removed);
    }
}

我不久前也遇到过类似的情况。当我单击正在删除的recyclerview项并正在进行删除动画时,该应用程序崩溃(不到一秒钟)。在这种情况下,您的应用程序易受潜在崩溃影响的持续时间非常短

我所做的:

当应用程序崩溃时,我记录了position(holder.getAdapterPosition())的值。令人惊讶的是,每次崩溃发生时,该值都是-1。最终,我编写了一个自定义版本的notifyItemRemoved。如下所示:

private void notifyItemRemovedModified(int pos_removed){
    if(pos_removed!=-1){
        // your list is your list
        yourList.remove(pos_removed);
        notifyItemRemoved(pos_removed);
    }
}

我对
notifyItemRemoved
的调用没有切断它?我认为这是一种更有效的方法,可以准确地告诉它发生了什么变化,因此它不必重新加载整个数据集。检查此链接:[我对
notifyItemRemoved
的调用没有切断它?我认为这是一种更有效的方式来准确地告诉它发生了什么变化,因此它不必重新加载整个数据集。检查此链接:[这不起作用。我不明白为什么会这样,但我只是测试了它。这不起作用。我不明白为什么会这样,但我只是测试了它而已。