RecyclerView实现长按多选删除

这里我先给出我的recyclerview每一个item的布局:
<LinearLayout
        android:id="@+id/root_view"//根布局要有id
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:background="#fff"
        android:descendantFocusability="blocksDescendants">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:paddingTop="18dp"
            android:paddingBottom="18dp"
            android:paddingLeft="18dp"
            android:layout_weight="1">

            <TextView
                android:id="@+id/notes_content_part"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textSize="16sp"
                android:textColor="#000"/>

            <TextView
                android:id="@+id/notes_time"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="8dp"
                android:textSize="12sp"
                android:textColor="#c1c1c1"/>

        </LinearLayout>

        <ImageView
            android:id="@+id/check_box"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_marginRight="15dp"
            android:src="@mipmap/circhose"
            android:visibility="gone"/>

    </LinearLayout>

    <View
        android:id="@+id/updownline"
        android:layout_width="match_parent"
        android:layout_height="0.5dp"
        android:background="#c1c1c1"/>

很简单的一个布局,这里我定义了两个textview,一个用来显示内容,一个用来显示当前时间,imageview是用来响应长按后出现的点击图标,因为recyclerview不自带下划线,所以这里我们定义了view来实现分割线。

每个item的布局
选中后的布局
选则的布局
接下来我们在recyclerview的是适配器中实现长按以及单点效果:

先来一堆代码为敬:

private List<Notes> list;//Notes是我们上面布局所对应的类,这里就不贴了
    private Context context;//从acticity中获取context

    private OnItemLongClickListener onItemClickListener;//实现长按监听的接口(自己实现)
    private OnItemClickListener onItemClick;//实现单点监听的接口(自己实现)
    private Boolean longclick = false;//判断目前recyclerview的状态是处于长按后还是长按前(防止前后的单点时间冲突)
    private Boolean choose = true;//长按状态是判断当前item是否被选中

    //用来在activity中初始化适配器
    public NotesAdapter(List<Notes> list,Context context) {
        this.list = list;
        this.context = context;
    }

    //这里就不详述了(可以参照我之前的RecyclerView简单使用)
    @Override
    public NotesAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(context).inflate(R.layout.notes_card,null,false);
        ViewHolder holder = new ViewHolder(view);
        return holder;
    }

    @Override
    public void onBindViewHolder(final NotesAdapter.ViewHolder holder, final int position) {
        Notes notes = list.get(position);
        holder.notes_content_part.setText(notes.getNotes_content_part());

        if(longclick) {
            holder.check_box.setVisibility(View.VISIBLE);//如果当前为长按状态则让长按选择图片显示
        } else {
            holder.check_box.setVisibility(View.GONE);//否则让其消失
        }

        holder.root_view.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                /*
                * 长按状态的逻辑
                * if语句中是根据当前长按图片所显示的图来判断是否被选中
                * */
                if(longclick) {
                    if (holder.check_box.getDrawable().getCurrent().getConstantState().
                            equals(context.getResources().getDrawable(R.mipmap.circhosetouch).getConstantState())) {
                        holder.check_box.setImageResource(R.mipmap.circhose);//点击后更换图为未选中
                        holder.root_view.setBackground(context.getDrawable(R.color.white));//点击后真个item布局变色
                        choose = false;//将choose设置为未选中态
                    } else {
                        holder.check_box.setImageResource(R.mipmap.circhosetouch);
                        holder.root_view.setBackground(context.getDrawable(R.color.longtouch));
                        choose = true;
                    }
                    onItemClick.OnItemClick(position,choose,list);//将当前选中的位置以及状态通过自定义接口在activity中使用
                } else if (!longclick) {  //正常状态的逻辑
                    Toast.makeText(context,"点了一下",Toast.LENGTH_SHORT).show();
                }
            }
        });
    }

    @Override
    public int getItemCount() {
        return list.size();
    }

    public class ViewHolder extends RecyclerView.ViewHolder{
        LinearLayout root_view;
        TextView notes_content_part;
        TextView notes_time;
        View updownline;
        ImageView check_box;

        public ViewHolder(View itemView) {
            super(itemView);
            notes_content_part = itemView.findViewById(R.id.notes_content_part);
            notes_time = itemView.findViewById(R.id.notes_time);
            updownline = itemView.findViewById(R.id.updownline);
            check_box = itemView.findViewById(R.id.check_box);
            root_view = itemView.findViewById(R.id.root_view);
            //用root_view的长按点击来实现整个item的长按点击
            root_view.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View view) {
                    onItemClickListener.OnItemLongClick();//实现自定义长按
                    longclick = true;//令recyclerview处于长按状态
                    return true;
                }
            });

        }

    }

    //删除Notes
    public void removeNotes(int postion) {
        list.remove(postion);
        notifyDataSetChanged();
    }
    //定义长按接口
    public interface OnItemLongClickListener {
        void OnItemLongClick();
    }
    //定义单点接口
    public interface OnItemClickListener {
        void OnItemClick(int x,boolean adro,List<Notes> list);//这里的List<Notes> list是因为要在数据库中删除传的,没有需求的小伙伴可以不用
    }
    //定义长按接口的实现
    public void setOnItemClickListener(OnItemClickListener onItemClick) {
        this.onItemClick = onItemClick;
    }
    定义单点接口的实现
    public void setOnItemLongClickListener(OnItemLongClickListener onItemClickListener){
        this.onItemClickListener = onItemClickListener;
    }
下来就是在activity中的实现了:
final List<Integer> stringList = new ArrayList<>();//定义list存储要删除的数
        //实现recyclerview加载
        LinearLayoutManager manager = new LinearLayoutManager(context);
        recyclerView.setLayoutManager(manager);
        final NotesAdapter adapter = new NotesAdapter(list, context);
        recyclerView.setAdapter(adapter);
        //实现长按事件
        adapter.setOnItemLongClickListener(new NotesAdapter.OnItemLongClickListener() {
            @Override
            public void OnItemLongClick() {
                    adapter.notifyDataSetChanged();//更新adapter目的是当长按一个item后所有的item都进入长按状态                
                    delete.setVisibility(View.VISIBLE);//长按后底部出现的删除按钮
            }
        });
        //实现单点事件
        adapter.setOnItemClickListener(new NotesAdapter.OnItemClickListener() {
            @Override
            public void OnItemClick(int x, boolean adro,List<Notes> list1) {//这里将所选位置一个状态穿了过来
                if(adro) {
                    stringList.add(x);//如果为选中状态,则添加
                } else  {
                    //否则,删除当前list中的选中值
                    for(int i = 0 ; i < stringList.size() ; i++) {
                        if(stringList.get(i) == x) {
                            stringList.remove(i);
                        }
                    }
                }
                Collections.sort(stringList);//从小到大对list排序,为了后面删除的方便
            }

        });
        //实现点击浮出的删除后进行删除
        delete.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //遍历整个list,如果位置为0直接删除,否则用当前list的值减去之前删除的个数再删除
                //因为当你删除一个值以后会更新整个recyclerview,这时他的长度发生改变而你存储的删除位置却没变,会导致错删,因为之前我们对其排过序所以没有先删大后删小的情况
                for(int i = 0 ; i < stringList.size() ; i++) {
                    if(i == 0) adapter.removeNotes(stringList.get(i));
                    else adapter.removeNotes(stringList.get(i)-i);
                }
                stringList.removeAll(stringList);//清空表(完成一次删除后立刻清空list表)
            }
        });

这样就可以简单的实现recyclerview的长按多选删除了