手记

关于自定义View的移动/拖拽总结

一、

one。 通过改变view 在父空间的layout位置来移动,  但是只能移动指定的view:

view.layout(l,t,r,b);

view.offsetLeftAndRight(offset);

view.offsetTopAndBottom(offset);


    two。通过改变scrollX 和 scrollY 来移动,  但是 可以移动所有的子view

scrollTo(x,y);   x,y  将要滚动到的位置

scrollBy(xOffset,yOffset);  滚动的偏移量


    three。通过改变canvas 绘制的位置来移动view 的内容(不常用)

canvas.drawBitmap(bitmap,l,t,paint);


二、使用ViewDragHelper来处理移动

one。ViewDragHelper  在 support  v4中  如要导入v4包

two。主要用于处理ViewGroup中对子View的拖拽处理

three。在Google2013年大会中提出

four。主要封装了对View的触摸位置,触摸速度,移动距离等的检测和Scroller,

five。本质是对触摸事件的解析类

通过接口回调的方式告诉我们;只需要我们指定是否需要移动,移动多少等。

   use:forParent 父View sensitivity 敏感度 默认为1.0f cb 回调接口

ViewDragHelper mViewDragHelper=ViewDragHelper.create(

ViewGroup forParent, float sensitivity, Callback cb

)

如果使用ViewDragHelper 需要重写两个事件

 //    拦截触摸事件
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return mViewDragHelper.shouldInterceptTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
//        处理拖拽事件
        mViewDragHelper.processTouchEvent(event);
        return true;
    }


  /**
     * 回调
     */
    private class MyCallBack extends ViewDragHelper.Callback {
        /**
         * * 用于判断是否捕捉当前 child 的触摸事件
         *
         * @param child  当前触摸的子View
         * @param pointerId 尝试捕获id 的 指针
         * @return true 捕获别切 解析 false 不处理
         */
        @Override
        public boolean tryCaptureView(View child, int pointerId) {
            return child == redView || child == blueView;
        }

        /**
         * 当view 被开始捕获和解析的回调  用处不太大
         *
         * @param capturedChild   当前被捕获的子View
         * @param activePointerId
         */
        @Override
        public void onViewCaptured(View capturedChild, int activePointerId) {
            super.onViewCaptured(capturedChild, activePointerId);
           
        }

        /**
         * 获取view 水平方向的拖范围  但是目前不能限制边界,
         * 在 clampViewPositionHorizontal 计算实现
         * 返回的值用在手指抬起的时候,view缓慢移动的动画的时间计算上面
         *
         * @param child
         * @return 最好不要返回 0
         */
        @Override
        public int getViewHorizontalDragRange(View child) {
            return getMeasuredWidth() - child.getMeasuredWidth();
        }

        /**
         * 获取view 垂直方向的拖范围  但是目前不能限制边界,
         * 在 clampViewPositionVertical 计算实现
         * 返回的值用在手指抬起的时候,view缓慢移动的动画的时间计算上面
         *
         * @param child
         * @return 最好不要返回 0
         */
        @Override
        public int getViewVerticalDragRange(View child) {
            return getMeasuredHeight() - child.getMeasuredHeight();
        }

        /**
         * 控制child在 水平方向的移动 clamp ->修正
         *
         * @param child
         * @param left  表示ViewDragHelper 认为你想让当前child的left改变的值
         *              left=child.getLeft() + dx;
         * @param dx    相对于 控件移动前,水平移动的距离
         *              负数为向左边移动正数为向右边移动
         * @return 表示真正你想让child的left 改变成的值
         */
        @Override
        public int clampViewPositionHorizontal(View child, int left, int dx) {
//            如果不想让view 水平移动 return left - dx 或者 child.getLeft();
            return left;
        }

        /**
         * 控制child在 垂直方向的移动 clamp ->修正
         *
         * @param child
         * @param top   表示ViewDragHelper 认为你想让当前child的top改变的值
         *              top=child.getTop() + dy;
         * @param dy    相对于 控件移动前,水平移动的距离
         *              负数为向左边移动正数为向右边移动
         * @return 表示你真正想让child的top 改变成的值
         */
        @Override
        public int clampViewPositionVertical(View child, int top, int dy) {
            return top;
        }

        /**
         * 当child 位置改变的时候执行  一般用来做其它子view 的伴随移动
         *
         * @param changedView 位置改变的 child
         * @param left        child 当前最新的left
         * @param top         child 当前最新的top
         * @param dx          本次水平移动的距离  因为每一次滑动都不一样
         * @param dy          本次垂直移动的距离  为每一次滑动都不一样
         */
        @Override
        public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
          
        }

        /**
         * 当手指抬起的时候会执行这个方法
         *
         * @param releasedChild 当前抬起的view
         * @param xvel          x方向移动的速度  正 向右移动  负数 向左移动
         * @param yvel          y方向移动的速度  正 向右移动  负数 向左移动
         */
        @Override
        public void onViewReleased(View releasedChild, float xvel, float yvel) {
            super.onViewReleased(releasedChild, xvel, yvel);
            if (releasedChild.getLeft() > getMeasuredWidth() / 2 - releasedChild.getMeasuredWidth() / 2) {
//                在右边  向右边缓慢移动  移动 view  到右边
                mViewDragHelper.smoothSlideViewTo(releasedChild,
                        getMeasuredWidth() - releasedChild.getMeasuredWidth(), releasedChild.getTop());
                ViewCompat.postInvalidateOnAnimation(DragLayout.this);
            } else {
//                在左边  向左边缓慢移动
                mViewDragHelper.smoothSlideViewTo(releasedChild, 0, releasedChild.getTop());
                ViewCompat.postInvalidateOnAnimation(DragLayout.this);
            }
        }

    }
    
    /**
     * 计算滚动 配合 mViewDragHelper.smoothSlideViewTo(releasedChild, 0, releasedChild.getTop());
     * 一直刷新界面
     */
    @Override
    public void computeScroll() {
//        如果继续移动  刷新界面
        if (mViewDragHelper.continueSettling(true)) {
            ViewCompat.postInvalidateOnAnimation(DragLayout.this);
        }
    }

原文链接:http://www.apkbus.com/blog-635104-61635.html

0人推荐
随时随地看视频
慕课网APP