1. 程式人生 > >RecyclerView的長按多選刪除操作

RecyclerView的長按多選刪除操作

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的長按多選刪除了