RecyclerView的拖動(dòng)排序與側(cè)滑刪除

本文將帶你一步一步的實(shí)現(xiàn)recyclerview的拖動(dòng)排序與側(cè)滑刪除
效果圖如下:

有圖有真相.gif

接下來(lái)就開始動(dòng)手啦!
先加入包吧

   compile 'com.android.support:recyclerview-v7:25.3.0'
   compile 'com.android.support:cardview-v7:25.3.0'

在activity_main.xml文件中只有一個(gè)RecyclerView

  <android.support.v7.widget.RecyclerView
       android:id="@+id/rv"
       android:layout_width="match_parent"
       android:layout_height="match_parent">
   </android.support.v7.widget.RecyclerView>

子布局item_rv.xml只有一個(gè)TextView

 <android.support.v7.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:minHeight="40dp"
        android:id="@+id/card"
        app:cardCornerRadius="5dp"
        >
        <TextView
            android:id="@+id/title"
            android:layout_gravity="center"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="23sp"
            android:text="title"/>
    </android.support.v7.widget.CardView>

接下來(lái)為Recyclerview定義一個(gè)Adapter并且繼承自RecyclerView.Adapter

  
public class RvAdapter extends RecyclerView.Adapter<RvAdapter.ViewHolder> {
    private List<String> mData;
    public List<String> getDataList(){
        return mData;
    }
    public RvAdapter(List<String> mData) {
        this.mData
                = mData;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater
                .from(parent.getContext())
                .inflate(R.layout.item_rv, null);
        return new ViewHolder(view);
    }

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

        ViewHolder mHolder = holder;
        mHolder.title.setText(mData.get(position));
    }

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

    static class ViewHolder extends RecyclerView.ViewHolder {
        TextView title;
        public ViewHolder(View itemView) {
            super(itemView);
            title= (TextView) itemView.findViewById(R.id.title);
        }
    }

    public void onItemDissmiss(int position) {
        //移除數(shù)據(jù)
        mData.remove(position);
        notifyItemRemoved(position);
    }

}

在MainActivity里面找到RecyclerView并且設(shè)置它的layoutManager和Adapter,這樣就完成了一個(gè)列表

        rv= (RecyclerView) findViewById(R.id.rv);
        LinearLayoutManager layoutManager=new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false);
//      GridLayoutManager layoutManager=new GridLayoutManager(this,3,GridLayoutManager.VERTICAL,false);
        RvAdapter adapter=new RvAdapter(mData);
        rv.setLayoutManager(layoutManager);
        rv.setAdapter(adapter);

接下來(lái)才是真正實(shí)現(xiàn)拖動(dòng)和側(cè)滑刪除的時(shí)候呢。用的SDK提供的ItemTouchHelper這個(gè)工具類,它需要一個(gè)CallBack回調(diào)函數(shù),這里我們使用ItemTouchHelper.Callback由于ItemTouchHelper.Callback是一個(gè)抽象函數(shù),所以需要新建一個(gè)類去繼承它。


public class DragItem extends ItemTouchHelper.Callback {
    private RvAdapter adapter;
    public DragItem(RvAdapter adapter) {
        this.adapter = adapter;
    }

    /**
     * 返回滑動(dòng)的方向
     * @param recyclerView
     * @param viewHolder
     * @return
     */
    @Override
    public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
        int dragFlag;
        int swipeFlag;
        RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
        if (layoutManager instanceof GridLayoutManager) {
            //允許上下左右的拖動(dòng)
            dragFlag = ItemTouchHelper.DOWN
                    | ItemTouchHelper.UP
                    | ItemTouchHelper.RIGHT
                    | ItemTouchHelper.LEFT;

            swipeFlag=0;
        }else{
            dragFlag=ItemTouchHelper.DOWN|ItemTouchHelper.UP;
            swipeFlag=ItemTouchHelper.LEFT;//只允許從右到左的側(cè)滑
        }
        return makeMovementFlags(dragFlag,swipeFlag);
    }

    /**
     * 當(dāng)用戶拖動(dòng)一個(gè)item從舊的位置移動(dòng)到新的位置時(shí)會(huì)調(diào)用此方法
     * @param recyclerView
     * @param viewHolder
     * @param target
     * @return
     */
    @Override
    public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {

        int fromPosition = viewHolder.getAdapterPosition();
        int toPosition = target.getAdapterPosition();
        if (fromPosition < toPosition) {
            for (int i = fromPosition; i < toPosition; i++) {
                Collections.swap(adapter.getDataList(), i, i + 1);
            }
        } else {
            for (int i = fromPosition; i > toPosition; i--) {
                Collections.swap(adapter.getDataList(), i, i - 1);
            }
        }
        recyclerView.getAdapter().notifyItemMoved(fromPosition, toPosition);
        return true;
    }

    /**
     * 當(dāng)用戶左右滑動(dòng)item達(dá)到刪除條件時(shí)會(huì)調(diào)用此方法
     * 一般達(dá)到item的一般寬度時(shí)才會(huì)刪除,否則彈回原位置
     * @param viewHolder
     * @param direction
     */
    @Override
    public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
        int position = viewHolder.getAdapterPosition();
        if (direction == ItemTouchHelper.END) {
            adapter.getDataList().remove(position);
            adapter.notifyItemRemoved(position);
        }
        adapter.onItemDissmiss(position);
    }

    /**
     * 當(dāng)某個(gè)item由靜止?fàn)顟B(tài)變?yōu)榛瑒?dòng)或拖動(dòng)狀態(tài)時(shí)調(diào)用此方法
     * @param viewHolder
     * @param actionState
     */
    @Override
    public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
        super.onSelectedChanged(viewHolder, actionState);
        if(actionState==ItemTouchHelper.ACTION_STATE_DRAG){
            viewHolder.itemView.setBackgroundColor(Color.GRAY);
        }
    }

    /**
     * 當(dāng)用戶操作完某個(gè)item動(dòng)畫結(jié)束時(shí)調(diào)用此方法
     * @param recyclerView
     * @param viewHolder
     */
    @Override
    public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
        super.clearView(recyclerView, viewHolder);
        viewHolder.itemView.setBackgroundColor(0);
    }

    /**
     * 是否支持長(zhǎng)按拖動(dòng)
     * 默認(rèn)返回true
     * @return
     */
    @Override
    public boolean isLongPressDragEnabled() {
        return true;
    }

    /**
     * 是否支持側(cè)滑刪除
     * 默認(rèn)返回true
     * @return
     */
    @Override
    public boolean isItemViewSwipeEnabled() {
        return true;
    }
}

各個(gè)方法的含義與調(diào)用時(shí)期在注釋中已經(jīng)說(shuō)得很清楚了,這里就不再重復(fù)了
最后只需要在MainActivity里面新建一個(gè)ItemTouchHelper并把CallBack傳進(jìn)去,再調(diào)用helper的attachToRecyclerView方法綁定recyclerView就可以啦

 ItemTouchHelper helper=new ItemTouchHelper(new DragItem(adapter));
 helper.attachToRecyclerView(rv);

當(dāng)然卡片式布局也是可以拖動(dòng)的

有圖有真相2.gif

最后附上項(xiàng)目的源代碼地址
https://github.com/HelloNanKe/RecyclerViewSwipeDrag

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容