坚持写博客备忘之ViewDragHelper(1)

相关介绍(抄别人的)

推荐工匠若水的博客

帮助我们方便的编写自定义ViewGroup

demo 搞起

public class MyLayout extends LinearLayout{
    private ViewDragHelper mDragHelper;
    private View view1,view2,view3;
    //保存原本的点
    private Point mAutoBackOriginPos = new Point();
    public MyLayout(Context context) {
        this(context,null);
    }

    public MyLayout(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }

    public MyLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mDragHelper=ViewDragHelper.create(this,1.0f,new ViewDragCallback());
        //设置触摸边缘会触发一些事件
        mDragHelper.setEdgeTrackingEnabled(ViewDragHelper.EDGE_LEFT);
    }
    private class ViewDragCallback extends ViewDragHelper.Callback {
        /**
         * 尝试捕获子view,一定要返回true
         * @param  view 尝试捕获的view
         * @param  pointerId 子view的id,返回什么什么可以移动
         * 这里可以决定哪个子view可以拖动
         */
        @Override
        public boolean tryCaptureView(View view, int pointerId) {

            return view==view1||view==view2;
        }

        /**
         * 处理水平方向上的拖动
         * @param  child 被拖动的view
         * @param  left 移动到达的x轴的距离
         * @param  dx 建议的移动的x距离
         */
        @Override
        public int clampViewPositionHorizontal(View child, int left, int dx) {

            //到最左边不继续移动防止越界
            if(getPaddingLeft() > left) {
                return getPaddingLeft();
            }
            //viewgroup的宽度 减去 子View的宽度 小于 移动的距离,防止越界
            if(getWidth() - child.getWidth() < left) {
                return getWidth() - child.getWidth();
            }

            return left;
        }

        /**
         *  处理竖直方向上的拖动
         * @param  child 被拖动到view
         * @param  top 移动到达的y轴的距离
         * @param  dy 建议的移动的y距离
         */
        @Override
        public int clampViewPositionVertical(View child, int top, int dy) {

            // 上边距
            if(getPaddingTop() > top) {
                return getPaddingTop();
            }
            // 计算允许向下移动的距离,然后比较,返回可移动的距离
            if(getHeight() - child.getHeight() < top) {
                return getHeight() - child.getHeight();
            }

            return top;
        }

        /**
         * 当拖拽到状态改变时回调
         * @params 新的状态
         */
        @Override
        public void onViewDragStateChanged(int state) {
            switch (state) {
                case ViewDragHelper.STATE_DRAGGING:  // 正在被拖动
                    break;
                case ViewDragHelper.STATE_IDLE:  // view没有被拖拽或者 正在进行fling/snap
                    break;
                case ViewDragHelper.STATE_SETTLING: // fling完毕后被放置到一个位置
                    break;
            }
            super.onViewDragStateChanged(state);
        }

        /**
         * 手指释放时的回调
         * 回到记录的位置
         * @param releasedChild
         * @param xvel
         * @param yvel
         */
        @Override
        public void onViewReleased(View releasedChild, float xvel, float yvel) {
            super.onViewReleased(releasedChild, xvel, yvel);
            if(releasedChild==view2){
                mDragHelper.settleCapturedViewAt(mAutoBackOriginPos.x,mAutoBackOriginPos.y);
                invalidate();
            }
        }

        /**
         * 触摸边缘时触发
         * @param edgeFlags
         * @param pointerId
         */
        @Override
        public void onEdgeDragStarted(int edgeFlags, int pointerId) {
            super.onEdgeDragStarted(edgeFlags, pointerId);
            mDragHelper.captureChildView(view3,pointerId);
        }
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        int action= MotionEventCompat.getActionMasked(ev);
        if(action==MotionEvent.ACTION_CANCEL||action==MotionEvent.ACTION_UP){
            mDragHelper.cancel();
            return false;
        }

        /**
         * 检查是否可以拦截touch事件
         * 如果onInterceptTouchEvent可以return true 则这里return true
         */
        return mDragHelper.shouldInterceptTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        /**
         * 处理拦截到的事件
         * 这个方法会在返回前分发事件
         */
        mDragHelper.processTouchEvent(event);
        return true;
    }


    // 实现fling效果
    @Override
    public void computeScroll() {
        super.computeScroll();
        //计算可以继续下降?
        if(mDragHelper.continueSettling(true)){
            invalidate();
        }
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        view1=findViewById(R.id.v1);
        view2=findViewById(R.id.v2);
        view3=findViewById(R.id.v3);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        //保存与左边的距离和与右边的距离
        mAutoBackOriginPos.x=view2.getLeft();
        mAutoBackOriginPos.y=view2.getTop();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值