android ViewDragHelper 實現抽屜滑動效果

                      

今天我要來講解一個比較常見的效果 就是抽屜式菜單 當滑動圖片的黃色部分 隱藏在底下下的藍色菜單欄就會被顯示出來 在谷歌2013大會上 公佈了一個 DrawerLayout 用來實現類似的效果 在此之前 基本上要在項目裏面使用 都是幾月github上第三方的控件  最近研究了一個 非常有用卻很少有人知道的view滑動處理類 ViewDragHelper 像在官方提供的 DrawerLayout 和PanelLayout中對拖拽和滑動時間的出來都是 基於ViewDragHelper 來實現的

之前自己也實現過類似的抽屜的效果 當時的實現方式是繼承HorizontalScrollView來實現的   在HorizontalScrollView中提供了滑動的事件以及對衝突的處理 有興趣的同學可以自己來實現看看

而今天我們要用 ViewDragHelper來實現這個效果

首先我們要明白 ViewDragHelper 只能作用於一個ViewGroup並對其中的子View的滑動進行處理 所以這裏我們需要自定義一個view 改view繼承自FrameLayout 因爲抽屜式的菜單總是在內容view之下的 這個正好符合

首先需要定義ViewDragHelper

 mDragHelper = ViewDragHelper.create(this, 1.0f, new DragHelperCallBack());

ViewDragHelper 中提供一個靜態的方法來創建對象。第一個參數表示的是一個父佈局 第二個參數表示敏感度 第三個參數是一個回調接口 ViewDragHelper.Callback 是和View 通訊的橋樑 大部分的動畫效果都是在這裏實現的 其中的回調函數也很多 這裏我們只用了其中幾個:

@Override
        public boolean tryCaptureView(View arg0, int arg1) {
            return arg0==childView;
        }

以上方法是用來處理那個view 是可以滑動的 返回爲true 是全部可滑動

@Override
        public int clampViewPositionHorizontal(View child, int left, int dx) {
            if(left <= 0)
                return 0;
            if(left >= mMenuWidth)
                return mMenuWidth;
            
            return left;
        }

以上方法是用來處理橫向滑動的 返回的值是滑動的距離 這裏我們處理了最小滑動的座標是0 最大爲menu的寬度

@Override
        public int getViewHorizontalDragRange(View child) {
            return mMenuWidth;
        }

以上方法是返回最大的橫向的滑動的距離

@Override
        public void onViewReleased(View releasedChild, float xvel, float yvel) {
            super.onViewReleased(releasedChild, xvel, yvel);
            Log.i("result",releasedChild.getLeft()+"");
            
            if(mState==STATE.close){
                if(releasedChild.getLeft()>=(mMenuWidth/2)){
                    open();
                }else{
                    close();
                }
            }
            if(mState==STATE.open){
                if(releasedChild.getLeft()>=(mMenuWidth/2)){
                    open();
                }else{
                    close();
                }
            }
        }


以上方法是用來處理當view滑動停止的會被調用 在這個方法裏 主要用來處理view的 滑動

view的滑動可以使用ViewDragHelper中的smoothSlideViewTo方法 當然還有一些特效比如透明的方法都是有的

這就看出啦VeewDragHelper類是多麼的強大

private void open(){
        mState =STATE.open;
        mDragHelper.smoothSlideViewTo(childView, mMenuWidth, 0);
        computeScroll();
    }
    private void close(){
        mState =STATE.close;
        mDragHelper.smoothSlideViewTo(childView, 0, 0);
        computeScroll();
    }

以上是自己定義的兩個處理打開很關閉的方法 用的就是smoothSlideViewTo

public void computeScroll() {
        if (mDragHelper.continueSettling(true)) {
            ViewCompat.postInvalidateOnAnimation(this);
        }
    }

ViewCompat.postInvalidateOnAnimation(this); 方法用來實現動畫效果 源碼中會調用Scroller來實現 有興趣的同學可以自己看一下

而在此之前 我們還有一個步驟要做  那就是要處理onTouchEVent 和 onInterceptTouchEvent 

public boolean onTouchEvent(MotionEvent event) {
        
       
        mDragHelper.processTouchEvent(event);
        return true;
    }


    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        int action = ev.getAction();
        return mDragHelper.shouldInterceptTouchEvent(ev);
    }

我們需要在這兩個方法中對ViewDragHelper的事件進行註冊 如果我們還需要在onTouchEvent中處理up 和down事件 一定要把註冊事件放在最前面 優先處理

下載地址:

http://download.csdn.net/detail/haoxuezhe1988/8811991


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