使用VeiwDragHelper类实现菜单侧滑效果

    相信大家都有用过QQ,而QQ上面的侧滑菜单大家都有使用过,这一设计给用户带来了不错的交互乐趣。ViewDragHelper顾名思义View托拽帮助类,一个在
2013的谷歌大会上提出来的一个类简化View拖拽的操作的类

要实现侧滑效果还需要导入一个android-support-v4.jar包,用来帮助实现拖拽效果和nineoldandroids-2.4.0.jar开源动画库

    private ViewGroup mLeftContent;
    private ViewGroup mMainContent;
    private int width;//子View测量的宽度
    private int height;//子View测量的高度
    private int dragRange;//子View拖拽的范围
    private Context context;
    private ViewDragHelper Mydraghelper;
**那么应该如何使用ViewDragHelper类来实现拖拽操作呢?**
一.ViewDragHelper类对象的创建
这里要传入三个参数
this-->代表ViewGroup对象
1.0f 表示拖拽的敏感度,1.0f表示最高
dragCallback-->一个Callback接口类对象,必须实现
Mydraghelper = ViewDragHelper.create(this,1.0f,dragCallback);

二。实现Callback接口中的某些方法
由于Callback方法中的方法比较多,在此只讲解一些需要完成侧滑效果而实现的方法
这里写图片描述

//返回值决定了哪些View可以进行拖拽,返回true表示所有的View可以进行拖拽      
        @Override
        public boolean tryCaptureView(View arg0, int arg1) {

            return arg0 == mMainContent || arg0 == mLeftContent;
        }
@Override
        /*决定了View水平方向拖拽到的位置 child-->拖拽的View
         * left-->view拖拽到的位置,距离父控件左边边缘的距离
         * dx -->拖拽的距离
         */
        public int clampViewPositionHorizontal(View child, int left, int dx) {

            if(child == mMainContent){
                left = dragtoleft(left);
            }
            return left;
        }

        private int dragtoleft(int left) {
            if(left<0){
                return 0;
            }else if(left>dragRange){
                left = dragRange;
            }
            return left;
        }
//返回一个大于0的数,否则无法进行拖拽
        @Override
        public int getViewHorizontalDragRange(View child) {
            return dragRange;
        }
//view坐标发生改变时,回调,从新设置布局
        @Override
        public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
                if(changedView == mLeftContent){

                    mLeftContent.layout(0, 0, width, height);
                    int newLeft = mMainContent.getLeft()+dx;
                    newLeft = dragtoleft(newLeft);
                    mMainContent.layout(newLeft, 0, newLeft+width, height);
                }
                //dispatchDragState(mMainContent.getLeft());
                animView(mMainContent.getLeft());
                invalidate();//解决低版本不能拖拽的问题
        }
//手指释放时回调-->  xve1表示手指释放时在X轴的速度,正向大于0,反向小于0
        @Override
        public void onViewReleased(View releasedChild, float xvel, float yvel) {

            if(xvel==0.0f&&mMainContent.getLeft()<0.5f*dragRange){
                close();
            }else if(xvel<0){
                close();
            }else{
                open();
            }
        }   

三.在自定义View中判断是要否拦截事件,将拦截的事件交给ViewDragHelper类来处理

//拦截触摸事件,判断是否进行拦截
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        // TODO Auto-generated method stub
        return Mydraghelper.shouldInterceptTouchEvent(ev);
    }
    //将拦截的事件进行处理,内部消费掉
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // TODO Auto-generated method stub
         Mydraghelper.processTouchEvent(event);
         return true;
    }

四.关于Callback中调用的一些自定义方法已经变量的说明

设置侧滑菜单的动画效果

private void animView(int left) {
        float percent = left * 1.0f / dragRange;
        //设置主界面缩放
        ViewHelper.setScaleX(mMainContent, 1.0f+(0.8f-1.0f)*percent);
        ViewHelper.setScaleY(mMainContent, 1.0f+(0.8f-1.0f)*percent);

        //设置左边界面的缩放
        ViewHelper.setScaleX(mLeftContent, 0.5f+(1.0f-0.5f)*percent);
        ViewHelper.setScaleY(mLeftContent, 0.5f+(1.0f-0.5f)*percent);

        //摄制左边界面的透明度变化
        ViewHelper.setAlpha(mLeftContent, 1.0f*percent);

        getBackground().setColorFilter(
                   (Integer) EvaluateUtil.evaluateArgb(percent, Color.BLACK, Color.TRANSPARENT),
                    Mode.SRC_OVER);
    }

设置侧滑菜单的打开与关闭

protected void open() {
            open(true);
        }

     public void open(boolean isSmooth) {
         int finalLeft = dragRange;
            if(isSmooth){
                Mydraghelper.smoothSlideViewTo(mMainContent, finalLeft, 0);
                invalidate();
            }
            else{
                mMainContent.layout(finalLeft, 0, finalLeft+width, height);
            }
     }
     protected void close() {
            close(true);
        }

        public void close(boolean isSmooth) {
            int finalLeft = 0;
            if (isSmooth) {
                // 平滑关闭
                // "触发"一个平滑动画, 计算了第一帧
                Mydraghelper.smoothSlideViewTo(mMainContent, finalLeft, 0);
                invalidate();
            } else {
                mMainContent.layout(finalLeft, 0, finalLeft + width, height);
            }
        }

//五.

    //布局加载完成后回调该函数
    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        if (getChildCount() < 2) {
            Log.i("duwenwne", "hahhaha");
            throw new RuntimeException("You must have at least 2 child views");
        }
        if (!(getChildAt(0) instanceof ViewGroup) || !(getChildAt(1) instanceof ViewGroup)) {
            Log.i("duwenwne", "hahhaha");
            throw new IllegalArgumentException("Your child views must be ViewGroup");
        }
        mLeftContent = (ViewGroup) getChildAt(0);
        mMainContent = (ViewGroup) getChildAt(1);
    }
//OnMearsure方法之后调用
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        width = mMainContent.getMeasuredWidth();//测量View的宽(测量的宽度)
        height = mLeftContent.getMeasuredHeight();
        dragRange = (int) (width*0.6f);
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值