Touch事件--对ViewDragHelper的理解

来源:互联网 发布:unity3d粒子系统爆炸 编辑:程序博客网 时间:2024/06/08 04:59

介绍

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详解