recyclerview 列表的item 拖拽 置頂 全選 刪除 功能

        很多時候我們需要對列表進行一些操作,比如說股票的自選列表 我們希望能夠拖拽刪除置頂等操作。在recyclerveiw 之前 我們使用listview 完成這些操作 有點點麻煩,但是在recyclerview 出來之後ItemTouchHelper類使得一切變得簡單。

       先上圖看下效果

 /**
     * Creates an ItemTouchHelper that will work with the given Callback.
     * <p>
     * You can attach ItemTouchHelper to a RecyclerView via
     * {@link #attachToRecyclerView(RecyclerView)}. Upon attaching, it will add an item decoration,
     * an onItemTouchListener and a Child attach / detach listener to the RecyclerView.
     *
     * @param callback The Callback which controls the behavior of this touch helper.
     */
    public ItemTouchHelper(Callback callback) {
        mCallback = callback;
    }

在我們創建 ItemTouchHelper 的時候 需要 傳遞一個Callback 對象。 官方的解釋是 控制觸摸事件的回調。也就是監聽我們對列表的拖拽事件。我們看看callback 中具體我們要重寫哪些回調

第一個就是  getMovementFlags 。

 /**
     * getMovementFlags 這個方法中我們可以設置拖拽和側滑的方向 比如說我們現在是縱向列表 拖拽 設置
     * makeMovementFlags(dragFlags, 0);第一個參數是拖拽的方向 ,我們設置的是ItemTouchHelper.UP | ItemTouchHelper.DOWN
     * 上或者下、因爲我們沒有側滑的需求所以swipeFlags 設置了0  如果我們的列表是網格列表 gridview
     * 我們也可以根據 recyclerView.getLayoutManager() 來判斷 然後
     * 設置 ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT
     *
     *  如果是側滑 我們需要把swipeFlags 設置成ItemTouchHelper.START | ItemTouchHelper.END
     * @param recyclerView
     * @param viewHolder
     * @return
     */
    @Override
    public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
        int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN ;
        return makeMovementFlags(dragFlags, 0);
    }

第二個方法是 onMove 每次 拖動都會觸發這個回調,每次回調我們可以在我們 adapter 中 操作我們的數據 每次拖動後我們把我們列表綁定書數組裏 數據的位置也做下調整。

 /**
     * 顧名思義 當我們把一個 item 從一個位置拖到另一個位置 會觸發這個回調
     * @param recyclerView
     * @param viewHolder ;老的 位置
     * @param target  新的位置
     * @return
     */
    @Override
    public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
        interfaceTouchHelper.onItemMove(viewHolder, viewHolder.getAdapterPosition(), target.getAdapterPosition());
        return true;
    }
public void onItemMove(RecyclerView.ViewHolder holder, int fromPosition, int toPosition) {

        if (fromPosition < toPosition) {
            for (int i = fromPosition; i < toPosition; i++) {
                Collections.swap(data, i, i + 1);
            }
        } else {
            for (int i = fromPosition; i > toPosition; i--) {
                Collections.swap(data, i, i - 1);
            }
        }
        //刷新列表
        notifyItemMoved(fromPosition, toPosition);
    }

其他 需要重寫的方法

/**
     * 當選中的時候對 item進行 設置效果 放大 縮小 或者高亮
     * @param viewHolder
     * @param actionState
     */
    @Override
    public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
        if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
            interfaceTouchHelper.onItemSelect(viewHolder);
        }
        super.onSelectedChanged(viewHolder,actionState);
    }

    /**
     * 拖拽 結束後 我們 要對之前 做的 效果進行清除。 恢復正常狀態
     * @param recyclerView
     * @param viewHolder
     */
    @Override
    public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
        if (!recyclerView.isComputingLayout()) {
            interfaceTouchHelper.onItemClear(viewHolder);
        }
        super.clearView(recyclerView,viewHolder);
    }

  /**
     * 如果我們需要動態設置 能否拖動,則重寫 isLongPressDragEnabled()方法 動態賦值,默認是true 的
     * @return
     */
    @Override
    public boolean isLongPressDragEnabled() {
        return isDrag;
    }

我們寫一個接口類 來處理選中 置頂 等 操作 

public interface InterfaceOnCheckOrClickListener {
    /**
     * 點擊拖動
     */
    void onViewDragStart(MotionEvent event);

    /**
     * 停止拖動
     */
    void onViewDragStop();

    /**
     * 置頂點擊事件
     * @param view
     * @param position
     */
    void onViewClick(View view, int position);

    /**
     * 選中的CheckBox
     * @param view
     * @param position
     */
    void onCheckBoxSelected(View view, int position);
}

在我們的activity 中 繼承這個接口 重寫 onViewClick 方法

 /**
     * 點擊置頂
     * @param view
     * @param position
     */
    @Override
    public void onViewClick(View view, int position) {
        for (int i = position; i > 0; i--) {
            Collections.swap(myAdapter.getData(), i, i - 1);
        }
        myAdapter.notifyDataSetChanged();
    }

還有一些具體的代碼實現不再贅述 直接上源碼吧。

代碼地址 :https://github.com/fyhsgsgssg/RecyclerViewTouchHelper

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章