Touch事件--对ViewDragHelper的理解

介绍

ViewDragHelper是对滑动事件的封装类。他用于ViewGroup中。

之前我们自定义滑动的View自己来实现dispatchTouchEvent会比较复杂,例如,我们自己实现一个SlidingMenu,需要定义一个ViewGroup,然后在onTouchEvent、onInterceptTouchEvent做很多复杂的判断。写起来效率也比较低。

通过ViewDragHelper,可以大大提高完成一个滑动效果的效率。

使用

1.  实例化。

mViewDragHelper = ViewDragHelper.create(this, 1.0f, callback());

参数一,表示要监听滑动事件的ViewGroup对象。

参数二,表示灵敏度。1.0f正常灵敏度

参数三,回调,这个参数比较重要。其中的实现决定了我们对滑动事件的处理。

callBack的回调的意义

new ViewDragHelper.Callback() {

            /**
             * 判断哪个View可以拖拽
             * @param child
             * @param pointerId
             * @return
             */
            @Override
            public boolean tryCaptureView(View child, int pointerId) {
                Log.i("tag", "start tryCapture");
                return child == mHeadView;
            }

            /**
             * 返回值,拖拽View移动的距离,左边距
             * @param child
             * @param left
             * @param dx
             * @return
             */
            @Override
            public int clampViewPositionHorizontal(View child, int left, int dx) {
                int newLeft = left;
                if (left < getPaddingLeft()) {
                    newLeft = getPaddingLeft();
                } else if (left > getMeasuredWidth() - child.getMeasuredWidth()) {
                    newLeft = getMeasuredWidth() - child.getMeasuredWidth();
                }
                return newLeft;
            }

            /**
             * 返回值,拖拽View移动的距离,上边距
             * @param child
             * @param top
             * @param dy
             * @return
             */
            @Override
            public int clampViewPositionVertical(View child, int top, int dy) {
                if (child == mSecView) {
                    return child.getTop();
                }
                int newTop = top;
                if (top < getPaddingTop()) {
                    newTop = getPaddingTop();
                } else if (top > getMeasuredHeight() - child.getMeasuredHeight()) {
                    newTop = getMeasuredHeight() - child.getMeasuredHeight();
                }
                return newTop;
            }

            @Override
            public void onViewReleased(View releasedChild, float xvel, float yvel) {
                super.onViewReleased(releasedChild, xvel, yvel);
                if (releasedChild == mSecView) {
                    Log.i("tag", "released xvel=" + xvel + ", yvel=" + yvel+", left="+releasedChild.getLeft() +", scroll="+releasedChild.getScrollX());

                    if (releasedChild.getLeft() > getMeasuredWidth() / 2 || xvel > 0) {
                        mViewDragHelper.settleCapturedViewAt(getMeasuredWidth() - releasedChild.getMeasuredWidth(), releasedChild.getTop());
                        invalidate();
                    } else {
                        mViewDragHelper.settleCapturedViewAt(0, releasedChild.getTop());
                        invalidate();
                    }
                }
            }

            /**
             * 当边沿触控到时回调
             * @param edgeFlags
             * @param pointerId
             */
            @Override
            public void onEdgeTouched(int edgeFlags, int pointerId) {
                super.onEdgeTouched(edgeFlags, pointerId);
                Log.i("tag", "edgeTouched edgeFlags=" + edgeFlags + ", pointerId=" + pointerId);
                //对mSecView进行滑动捕获,可以绕过tryCaptureView
                mViewDragHelper.captureChildView(mSecView, pointerId);
            }

            /**
             * 当在边沿拖拽时回调
             * @param edgeFlags
             * @param pointerId
             */
            @Override
            public void onEdgeDragStarted(int edgeFlags, int pointerId) {
                super.onEdgeDragStarted(edgeFlags, pointerId);
                Log.i("tag", "edgeTouched edgeFlags=" + edgeFlags + ", pointerId=" + pointerId);
                //对mSecView进行滑动捕获,可以绕过tryCaptureView
                mViewDragHelper.captureChildView(mSecView, pointerId);
            }

            /**
             * 如果viewGroup有获取焦点的控件(例如button,editText)等,如果想滑动,此处不能返回0
             * @param child
             * @return
             */
            @Override
            public int getViewHorizontalDragRange(View child) {
                return super.getViewHorizontalDragRange(child);
            }
        });

2. 将事件传递给ViewDragHelper处理。

ViewDragHelper定义好了以后,我们要把需要处理的触摸事件传递给他。

 /**
     * onInterceptTouchEvent应该有viewDragHelper来控制
     *
     * @param ev
     * @return
     */
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return mViewDragHelper.shouldInterceptTouchEvent(ev);
    }

    /**
     * onTouchEvent应该有viewDragHelper控制
     *
     * @param event
     * @return
     */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        mViewDragHelper.processTouchEvent(event);
        return true;
    }

至此,通过ViewDragHeler已能实现拖动。

ViewDragHelper常用方法解释

//对mSecView进行滑动捕获,可以绕过tryCaptureView.将滑动事件传递给mSecView
    mViewDragHelper.captureChildView(mSecView, pointerId);
    //让View滑动到指定的位置,常配合 invalidate,computeScroll,mDragHelper.continueSettling使用
   mViewDragHelper.settleCapturedViewAt(getMeasuredWidth() - releasedChild.getMeasuredWidth(), releasedChild.getTop());    
    //是否持续滚动
    mDragHelper.continueSettling(true);

参考

Android ViewDragHelper完全解析

ViewDragHelper详解




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值