RecyclerView之拖拽滑動

recyclerview控件大家已經用的非常熟悉了,最近開發時做仿微信發送朋友圈注意到微信選完圖片之後可以對圖片進行拖拽刪除,所以進行了嘗試,其實recyclerview本身已經提供了幫助類,主要是繼承其回調,下面對代碼進行講解分析。

public class RecyclerCallBack extends ItemTouchHelper.Callback {

    private int dragFlags;
    private int swipeFlags;
    private ImgAdapter adapter;
    private boolean up;
    private Context mContext;

    public RecyclerCallBack(Context context, ImgAdapter adapter) {
        this.adapter = adapter;
        this.mContext = context;
    }

    /**
     * 設置item是否處理拖拽事件和滑動事件,以及拖拽和滑動操作的方向 .
     * 如果直接返回0 表明不支持進行拖動和滑動 .
     * @param recyclerView .
     * @param viewHolder  .
     * @return .
     */
    @Override
    public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
        //判斷 recyclerView的佈局管理器數據
        if (recyclerView.getLayoutManager() instanceof StaggeredGridLayoutManager) {
             //表示可以對其進行上下左右的拖動
             dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
            //0則不響應事件
            swipeFlags = 0;
        }
        return makeMovementFlags(dragFlags, swipeFlags);
    }

    /**
     * 當用戶從item原來的位置拖動可以拖動的item到新位置的過程中調用 .
     * @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 (toPosition == adapter.getDatas().size() - 1 || adapter.getDatas().size() - 1 == fromPosition) {
            return true;
        }
        //表示對數據進行新的排序 .
        if (fromPosition < toPosition) {
            for (int i = fromPosition; i < toPosition; i++) {
                Collections.swap(adapter.getDatas(), i, i + 1);
            }
        } else {
            for (int i = fromPosition; i > toPosition; i--) {
                Collections.swap(adapter.getDatas(), i, i - 1);
            }
        }
        adapter.notifyItemMoved(fromPosition, toPosition);
        return true;
    }

    /**
     * 設置是否支持長按拖拽 .
     * @return .
     */
    @Override
    public boolean isLongPressDragEnabled() {
        return false;
    }

    /**
     * @param viewHolder .
     * @param direction .
     */
    @Override
    public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {

    }

    /**
     * 當用戶與item的交互結束並且item也完成了動畫時調用 .
     * @param recyclerView .
     * @param viewHolder .
     */
    @Override
    public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
        super.clearView(recyclerView, viewHolder);
        adapter.notifyDataSetChanged();
        initData();
        if (dragListener != null) {
            dragListener.clearView();
        }
    }

    /**
     * 重置 .
     */
    private void initData() {
        if (dragListener != null) {
            dragListener.deleteState(false);
            dragListener.dragState(false);
        }
        up = false;
    }

    /**
     * 自定義拖動與滑動交互 .
     * @param c  .
     * @param recyclerView .
     * @param viewHolder .
     * @param dX .
     * @param dY .
     * @param actionState .
     * @param isCurrentlyActive .
     */
    @Override
    public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
        if (null == dragListener) {
            return;
        }

        if (dY >= (recyclerView.getHeight()
                - viewHolder.itemView.getBottom()
                - mContext.getResources().getDimensionPixelSize(R.dimen.dp_44))) {
            dragListener.deleteState(true);
            if (up) {
                //先設置不可見,如果不設置的話,會看到viewHolder返回到原位置時才消失,因爲remove會在viewHolder動畫執行完成後纔將viewHolder刪除
                viewHolder.itemView.setVisibility(View.INVISIBLE);
                adapter.getDatas().remove(viewHolder.getAdapterPosition());
                adapter.notifyItemRemoved(viewHolder.getAdapterPosition());
                initData();
                return;
            }
        } else {//沒有到刪除處 , 如果viewHolder不可見,則表示用戶放手,重置刪除區域狀態
            if (View.INVISIBLE == viewHolder.itemView.getVisibility()) {
                dragListener.dragState(false);
            }
            dragListener.deleteState(false);
        }
        super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
    }

    /**
     * 當長按選中item的時候(拖拽開始的時候)調用 .
     * @param viewHolder .
     * @param actionState  .
     */
    @Override
    public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
        if (ItemTouchHelper.ACTION_STATE_DRAG == actionState && dragListener != null) {
            dragListener.dragState(true);
        }
        super.onSelectedChanged(viewHolder, actionState);
    }

    /**
     * 設置手指離開後ViewHolder的動畫時間,在用戶手指離開後調用 .
     * @param recyclerView  .
     * @param animationType .
     * @param animateDx .
     * @param animateDy .
     * @return .
     */
    @Override
    public long getAnimationDuration(RecyclerView recyclerView, int animationType, float animateDx, float animateDy) {
        up = true;
        return super.getAnimationDuration(recyclerView, animationType, animateDx, animateDy);
    }

    interface DragListener {
        /**
         * 用戶是否將 item拖動到刪除處,根據狀態改變顏色
         * @param delete
         */
        void deleteState(boolean delete);

        /**
         * 是否於拖拽狀態
         * @param start
         */
        void dragState(boolean start);

        /**
         * 當用戶與item的交互結束並且item也完成了動畫時調用
         */
        void clearView();
    }

    private DragListener dragListener;

    void setDragListener(DragListener dragListener) {
        this.dragListener = dragListener;
    }

}

 

 

 

 

 

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