ViewDragHelper一個幫助你輕鬆完成滑動操作的輔助類

通過我們來處理自定義ViewGroup中子View滑動時,我們都是去通過事件攔截以及在onTouchEvent方法中進行手勢判斷,加速度檢測等。

在官方的V4提供了ViewDragHelper來幫助我們方便的編寫自定義ViewGroup時處理子View的滑動等相關的操作處理



代碼演示:

public class CustomViewGroup extends ViewGroup {

    View childView_1; //子View1
    View childView_2; //子View2 
    ViewDragHelper viewDragHelper;

    public CustomViewGroup(Context context) {
        super(context);

        // 第一個參數爲this,表示該類生成的對象,是ViewDragHelper的拖動處理對象,必須爲ViewGroup。
        //第二個參數1.0f是敏感度參數參數越大越敏感,默認就是1.0f。
        //第三個參數回調接口,是ViewDragHelper與View交互的橋樑
        viewDragHelper = ViewDragHelper.create(this, 1.0f, new ViewDragHelper.Callback() {
            /**
             *通過DragHelperCallback的tryCaptureView方法的返回值可以決定一個parentview中哪個子view可以拖動,
             *
             * @param child
             * @param pointerId
             * @return
             */

            @Override
            public boolean tryCaptureView(View child, int pointerId) {
                //return child==childView_1; 如果如此 設置 只有 childView_1可以被ViewDragHelper控制
                return true; //所有View都可以
                //有人問 想 控制兩個怎麼辦
                //return child == view1 || child == view2  >>>>>   484傻 ,其實是我問的
            }

            /**
             *該方法用來處理水平方向的滑動事件,返回目的值即可,但是爲了處理例如邊界情況,需要考慮到對象本身的邊界值
             * @param child 需要被處理的對象  可以用此來判斷(eg 只允許View1垂直滑動 ,判斷一下,如果是view1我就不做任何操作不就行了麼)
             * @param left 目的值(應該是以左邊的點爲依據)
             * @param dx
             * @return
             */
            @Override
            public int clampViewPositionHorizontal(View child, int left, int dx) {
                int left_bound = getPaddingLeft(); //左邊的邊界值
                int right_bound = getWidth() - getPaddingRight() - child.getWidth();//右邊的邊界值
                //這真是個有趣的表達式 第一步如果是左邊部分的話,肯定是取值比 左邊界要大,
                // 右邊部分的話(肯定比左邊界大了,內部的值Max取到的肯定是 left),取到的值要比右邊界小
                //主要是爲了 視圖越界 呈現在手機窗口的外面了
                return Math.min(Math.max(left, left_bound), right_bound);
            }

            /*
            * 這裏沒有什麼不同 只是垂直方向的罷了
            * */
            @Override
            public int clampViewPositionVertical(View child, int top, int dy) {
                int top_bound = getPaddingTop();//上邊界
                int bottom_bound = getHeight() - getPaddingBottom() - child.getHeight();//下邊界
                return Math.min(Math.max(top, top_bound), bottom_bound);
            }

            /**
             * 當設置了邊緣滑動事件的時候,一旦事件發生,該方法就會被回調,要是想要相關View跟着運動需要在代碼中執行
             * @param edgeFlags 邊緣的滑動標誌
             * @param pointerId
             */
            @Override
            public void onEdgeDragStarted(int edgeFlags, int pointerId) {
                //如此 第一個View就會跟着邊緣事件進行 觸發操作了
                viewDragHelper.captureChildView(childView_1, pointerId);

            }
        });


        //如果你想要處理左右邊緣的滑動事件 可以通過以下設置 >>例如設置左邊緣,如果想要監聽到相關事件還需要重寫回調中的一個方法
        //onEdgeDragStarted()
        viewDragHelper.setEdgeTrackingEnabled(ViewDragHelper.EDGE_LEFT);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        //該方法內部已經對相應的事件進行了過濾,至此直接將事件交給ViewDragHelper返回即可
        return viewDragHelper.shouldInterceptTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        //將事件拿到
        viewDragHelper.processTouchEvent(event);
        //表示消費該事件
        return true;
    }
    /**
     * 當View中所有的子控件 均被映射成xml後觸發
     */
    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        //小心空指針呀,要是你佈局文件裏沒有兩個子View,不就GG了麼 注意哈
        childView_1 = getChildAt(0);
        childView_2 = getChildAt(1);
    }
}

到此,我們的ViewDragHelper已經體驗了一番,下一章,我們介紹剩下的幾個特性,打造我們的側滑菜單.

發佈了36 篇原創文章 · 獲贊 5 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章