使用ViewDragHelper實現RecyclerView Item側滑

這里實現RecyclerView Item側滑只是為了學習ViewDragHelper,要是想追求很酷炫的側滑效果的話那就請移步github上面有很多。下面切入正題上這篇文章的主角ViewDragHelper。看名字就知道這是個幫助類是讓開發人員在自定義ViewGroups的時候更方便去操作子view的拖拽,其實還是方便了touch事件的操作,下面直接上這詞要實現的效果的gif圖:

側滑刪除

這種側滑效果很常見但是一直沒有自己動手實踐過,正好看見了這個幫助類就想起來實踐一把。剛才上面說道ViewDragHelper的主要作用其實所有控制子view移動拖拽的具體動作全部沒有在ViewDragHelper里面的方法而是用ViewDragHelper.CallBack這個回調來實現的里面有很多方法來控制子view的移動。
下面先上Item里面自定義的一個相對布局:

public class DragLin extends RelativeLayout {

    private ViewDragHelper viewDragHelper;
    //側滑item
    private View itemView;
    //刪除按鈕
    private View delView;

    private Point mPoint = new Point();

    public DragLin(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        //第一個參數是父布局這里就是當前布局第二個參數是敏感度默認是1.0f
        //第三個參數是一個ViewDragHelper.CallBack的實例里面控制子view的操作
        viewDragHelper = ViewDragHelper.create(this, 1.0f, new CallB());
    }

//讓viewDragHelper攔截touch事件
    @Override
    public boolean onInterceptHoverEvent(MotionEvent event) {
        return viewDragHelper.shouldInterceptTouchEvent(event);
    }
    //讓viewDragHelper消耗touch事件
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        viewDragHelper.processTouchEvent(event);
        return true;
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        mPoint.x = itemView.getLeft();
        mPoint.y = itemView.getTop();
    }
    
    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        itemView = getChildAt(1);
        delView = getChildAt(0);
    }
    //為了實現彈性滑動
    @Override
    public void computeScroll() {
        if (viewDragHelper.continueSettling(true)) {
            invalidate();
        }
    }


    public class CallB extends ViewDragHelper.Callback {

        private static final String TAG = "Dra";

//確定是那個view來被拖拽
        @Override
        public boolean tryCaptureView(View child, int pointerId) {
            return child == itemView;
        }

//橫向的可以移動的范圍
        @Override
        public int clampViewPositionHorizontal(View child, int left, int dx) {
            //左邊滑動的時候最多可以滑動到delitem完全顯示出來
            final int leftBound = getWidth() - delView.getWidth();
            //右邊滑動的時候最多滑動到itemview完全顯示
            final int rightBound = getWidth();
            final int newLeft = Math.min(Math.max(left, -delView.getWidth()), getPaddingLeft());
            return newLeft;
        }
        //當拖拽動作開始執行的時候

        @Override
        public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
            super.onViewPositionChanged(changedView, left, top, dx, dy);
            mPoint.x = left;

        }

//當手離開屏幕不在拖拽
        @Override
        public void onViewReleased(View releasedChild, float xvel, float yvel) {
            super.onViewReleased(releasedChild, xvel, yvel);
            if (-itemView.getX() > delView.getWidth() / 2) {
                //當滑動的位置超過了delview的一半的時候那么自動滑動到完全覆蓋狀態,高度不動
                viewDragHelper.settleCapturedViewAt(-delView.getWidth(), mPoint.y);
                invalidate();
            } else {
                //當滑動的位置不超過了delview的一半的時候那么還原到delview完全顯示狀態,高度不動
                viewDragHelper.settleCapturedViewAt(getPaddingLeft(), mPoint.y);
                invalidate();
            }
        }
    }
}

這就是整個完整的代碼,注意必須實現clampViewPositionHorizontal或者是clampViewPositionVertical這兩個方法其中的一個也就是說必須得給被拖拽的view一個可以移動的范圍要不不會實現移動的效果。2、computeScroll這個方法是為了實現彈性滑動(如果對彈性滑動不太熟悉的話可以百度學習一下)

其實側滑有很多種實現方式但是我相信這是最簡單的實現方式了,實在是受不了來回的去控制touch手勢,那簡直太痛苦了。

說起來可真是慚愧啊,鴻洋大神在15年的時候就發表過這方面的博客但是我卻現在才剛開始學習,這就是差距啊,每天學習新“姿勢”,努力更新中。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,334評論 25 708
  • 發現 關注 消息 iOS 第三方庫、插件、知名博客總結 作者大灰狼的小綿羊哥哥關注 2017.06.26 09:4...
    肇東周閱讀 12,241評論 4 61
  • 笑看人去悠自在, 樂土一方任風來。 愛慕年年霜雪雨, 喜展歲歲翠屏開。
    房謀杜斷28閱讀 362評論 0 0
  • ————————
    寒冰語閱讀 244評論 0 0
  • 今日嘆昨日, 明日嘆今日。 幾嘆成蹉跎, 萬事又為何。
    張一二閱讀 413評論 11 23