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