读书笔记之类似qq的侧滑菜单

        其实现在有很多第三方开源组件,大家觉得方便就会拿来用,而对其原理却不是很懂,以至于看源码都可能看不到,下面就讲一下简单的实现qq侧滑菜单的样式。

        重点是学习功能强大的ViewDragHelper类,首先要初始化ViewDragHelper,它通常定义在ViewGroup的内部,并通过其静态工厂方法进行初始化。

private void initView() {
    mViewDragHelper = ViewDragHelper.create(this, callback);
}

第一个参数为要监听的view,第二个是一个callback回调。这个回调就是ViewDragHelper的逻辑核心,后面再来做详细讲解。


接下来要重写事件拦截方法,然后将事件传递给ViewDragHelper进行处理,这个操作必不可少,相当于把触摸事件交给ViewDragHelper了。

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    return mViewDragHelper.shouldInterceptTouchEvent(ev);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    //将触摸事件传递给ViewDragHelper,此操作必不可少
    mViewDragHelper.processTouchEvent(event);
    return true;
}

使用ViewDragHelper同样需要重写computescroll方法,因为它的内部也是通过scroller来实现平滑移动的,可以使用模版代码。

@Override
public void computeScroll() {
    if (mViewDragHelper.continueSettling(true)) {
        ViewCompat.postInvalidateOnAnimation(this);
    }
}

接下来就是处理回调接口的实现。

private ViewDragHelper.Callback callback =
        new ViewDragHelper.Callback() {

            // 何时开始检测触摸事件
            @Override
            public boolean tryCaptureView(View child, int pointerId) {
                //如果当前触摸的child是mMainView时开始检测
                return mMainView == child;
            }

            // 触摸到View后回调
            @Override
            public void onViewCaptured(View capturedChild,
                                       int activePointerId) {
                super.onViewCaptured(capturedChild, activePointerId);
            }

            // 当拖拽状态改变,比如idle,dragging
            @Override
            public void onViewDragStateChanged(int state) {
                super.onViewDragStateChanged(state);
            }

            // 当位置改变的时候调用,常用与滑动时更改scale等
            @Override
            public void onViewPositionChanged(View changedView,
                                              int left, int top, int dx, int dy) {
                super.onViewPositionChanged(changedView, left, top, dx, dy);
            }

            // 处理垂直滑动
            @Override
            public int clampViewPositionVertical(View child, int top, int dy) {
                return 0;
            }

            // 处理水平滑动
            @Override
            public int clampViewPositionHorizontal(View child, int left, int dx) {
                return left;
            }

            // 拖动结束后调用
            @Override
            public void onViewReleased(View releasedChild, float xvel, float yvel) {
                super.onViewReleased(releasedChild, xvel, yvel);
                //手指抬起后缓慢移动到指定位置
                if (mMainView.getLeft() < 500) {
                    //关闭菜单
                    //相当于Scroller的startScroll方法
                    mViewDragHelper.smoothSlideViewTo(mMainView, 0, 0);
                    ViewCompat.postInvalidateOnAnimation(DragViewGroup.this);
                } else {
                    //打开菜单
                    mViewDragHelper.smoothSlideViewTo(mMainView, 300, 0);
                    ViewCompat.postInvalidateOnAnimation(DragViewGroup.this);
                }
            }
        };

还有两个方法


加载完布局文件后调用,来判断当前触摸谁的时候开始检测

@Override
protected void onFinishInflate() {
    super.onFinishInflate();
    mMenuView = getChildAt(0);
    mMainView = getChildAt(1);
}
如果需要根据view的宽度来处理滑动效果就可以根据这个
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    mWidth = mMenuView.getMeasuredWidth();
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值