美文网首页
ViewDragHelper

ViewDragHelper

作者: 起嚸_ | 来源:发表于2019-02-21 20:22 被阅读0次

原文:https://www.jianshu.com/p/d58e5766ae1c
https://www.jianshu.com/p/d78515acb4c6
ViewDragHelper是针对 ViewGroup 中的拖拽和重新定位 views 操作时提供了一系列非常有用的方法和状态追踪。基本上使用在自定义ViewGroup处理拖拽中!

public class DragLayout extends LinearLayout {

    private ViewDragHelper mDragger;
    private ImageView iv1;
    private Point initPointPosition = new Point ();

    @Override
    protected void onFinishInflate() {
        iv1 = (ImageView) this.findViewById (R.id.iv1);
        super.onFinishInflate ();
    }

    public DragLayout(Context context) {
        super (context);
    }

    public DragLayout(Context context, AttributeSet attrs) {
        super (context, attrs);
        ViewDragHelper.Callback callback = new DraggerCallBack ();
        //第二个参数就是滑动灵敏度的意思 可以随意设置
        mDragger = ViewDragHelper.create (this, 1.0f, callback);
    }

    class DraggerCallBack extends ViewDragHelper.Callback {

        /**
         * @param pointerId 表示触摸点的id, 比如多点按压的那个id
         * @return 是否可以capture, 也就是是否可以滑动.可以根据不同的child决定是否可以滑动
         */
        @Override
        public boolean tryCaptureView(View child, int pointerId) {
            return true;
        }

        /**
         * @param left 表示当前的view正要移动到左边距为left的地方
         * @param dx   表示和上一次滑动的距离间隔
         * @return 最终确定的移动的位置
         */
        @Override
        public int clampViewPositionHorizontal(View child, int left, int dx) {
            //取得左边界的坐标
            final int leftBound = getPaddingLeft ();
            //取得右边界的坐标
            final int rightBound = getWidth () - child.getWidth () - leftBound;
            return Math.min (Math.max (left, leftBound), rightBound);
        }

        @Override
        public int clampViewPositionVertical(View child, int top, int dy) {
            final int topBound = getPaddingTop ();
            final int bottomBound = getHeight () - child.getHeight () - topBound;
            return Math.min (Math.max (top, topBound), bottomBound);
        }

        @Override
        public void onViewReleased(View releasedChild, float xvel, float yvel) {
            //松手的时候 判断如果是这个view 就让他回到起始位置
            mDragger.settleCapturedViewAt (initPointPosition.x, initPointPosition.y);
            invalidate ();//postInvalidate
        }

        //如果需要滑动的View,会消耗touch事件,比如:Button,那么需要重写以下方法.
//        @Override
//        public int getViewHorizontalDragRange(View child) {
//            return child.getMeasuredWidth();//只要返回大于0的值就行
//        }
//
//        @Override
//        public int getViewVerticalDragRange(View child) {
//            return child.getMeasuredHeight();//只要返回大于0的值就行
//        }
    }

    @Override
    public void computeScroll() {
        if (mDragger.continueSettling (true)) {
            invalidate ();//postInvalidate
        }

    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout (changed, l, t, r, b);
        //布局完成的时候就记录一下位置
        initPointPosition.x = iv1.getLeft ();
        initPointPosition.y = iv1.getTop ();
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        //决定是否拦截当前事件
        return mDragger.shouldInterceptTouchEvent (ev);
    }

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

拖拽DEMO

public class DragView extends FrameLayout {
    ViewDragHelper helper;
    private View tv1;
    private View tv2;
    private int width;
    private float dragRange;
    FloatEvaluator floatEvaluator;

    public DragView(@NonNull Context context) {
        this(context,null);
    }

    public DragView(@NonNull Context context, @Nullable AttributeSet attrs) {
        this(context, attrs,0);
    }

    public DragView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        initData();
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        tv1 = getChildAt(0);
        tv2 = getChildAt(1);
    }

    private void initData() {
        floatEvaluator = new FloatEvaluator();
        helper = ViewDragHelper.create(this,callback);

    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        helper.processTouchEvent(event);
        return true;
    }

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

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        width = getMeasuredWidth();
        dragRange =  (width*0.6f);
    }

    ViewDragHelper.Callback callback = new ViewDragHelper.Callback() {
        @Override
        public boolean tryCaptureView(@NonNull View child, int pointerId) {
            return child == tv2;
        }

        @Override
        public void onViewPositionChanged(@NonNull View changedView, int left, int top, int dx, int dy) {
            super.onViewPositionChanged(changedView, left, top, dx, dy);

           executeAnim(changedView.getLeft()/dragRange);
        }

        @Override
        public int getViewHorizontalDragRange(@NonNull View child) {
            return (int) dragRange;
        }

        @Override
        public int clampViewPositionHorizontal(@NonNull View child, int left, int dx) {
            if(left<0){
                left = 0;
            }else if(left > dragRange){
                left = (int) dragRange;
            }
            return left;
        }

        @Override
        public void onViewReleased(@NonNull View releasedChild, float xvel, float yvel) {
            super.onViewReleased(releasedChild, xvel, yvel);
            if(releasedChild.getLeft() < dragRange/2){
                helper.smoothSlideViewTo(releasedChild,0,releasedChild.getTop());
                ViewCompat.postInvalidateOnAnimation(DragView.this);
            }else{
                helper.smoothSlideViewTo(releasedChild, (int) dragRange,releasedChild.getTop());
                ViewCompat.postInvalidateOnAnimation(DragView.this);
            }
        }
    };

    private void executeAnim(float fraction) {
        Float scaleValue = floatEvaluator.evaluate(fraction, 1, 0.8);
        tv2.setScaleX(scaleValue);
        tv2.setScaleY(scaleValue);
    }


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

相关文章

网友评论

      本文标题:ViewDragHelper

      本文链接:https://www.haomeiwen.com/subject/jrcfcqtx.html