Android自定义可拖动的悬浮布局

首先上效果图

拖动

这个自定义的View是继承RelativeLayout的,所以在写xml布局的时候直接当成RelativeLayout使用即可。

由于在该类中注释的很清楚,在这里我就不再累赘直接上代码

public class MyDragView extends RelativeLayout {

    private ViewDragHelper mDragger;

    private View mAutoBackView;

    public MyDragView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mDragger = ViewDragHelper.create(this, 1.0f, new ViewDragHelper.Callback() {
            @Override
            public int getViewHorizontalDragRange(View child) {
                 //返回可拖动的子视图的水平运动范围(以像素为单位)的大小。
                 //对于不能垂直移动的视图,此方法应该返回0。
                return getMeasuredWidth() - child.getMeasuredWidth();
            }

            @Override
            public int getViewVerticalDragRange(View child) {
                //返回可拖动的子视图的竖直运动范围(以像素为单位)的大小。
                //对于不能垂直移动的视图,此方法应该返回0。
                return getMeasuredHeight() - child.getMeasuredHeight();
            }

            @Override
            public boolean tryCaptureView(View child, int pointerId) {
                //返回true表view示捕获当前touch到的
                return true;
            }

            @Override
            public int clampViewPositionHorizontal(View child, int left, int dx) {
                if (left > getWidth() - child.getMeasuredWidth()){
                    //超出左侧边界处理
                    left = getWidth() - child.getMeasuredWidth();
                } else if (left < 0) {
                    //超出右侧边界处理
                    left = 0;
                }
                return left;
            }

            @Override
            public int clampViewPositionVertical(View child, int top, int dy) {
                if (top > getHeight() - child.getMeasuredHeight()){
                    //超出下边界处理
                    top = getHeight() - child.getMeasuredHeight();
                } else if (top < 0) {
                    //超出上边界处理
                    top = 0;
                }
                return top;
            }


        });
        mDragger.setEdgeTrackingEnabled(ViewDragHelper.EDGE_LEFT);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        return mDragger.shouldInterceptTouchEvent(event);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        //点击位置坐标
        int downX = (int) event.getX();
        int downY = (int) event.getY();
        //悬浮区域左上角坐标
        int x = (int) mAutoBackView.getX();
        int y = (int) mAutoBackView.getY();
        //悬浮区域宽高
        int width = mAutoBackView.getWidth();
        int height = mAutoBackView.getHeight();

        if ((downX >= x && downY >= y) && (downX <= (x+width) && downY <= (y+height)) ) {
            //点击在悬浮区域内部进行事件拦截,否则不拦截
            try {
                mDragger.processTouchEvent(event);
                return true;
            }catch (IllegalArgumentException e){
                return false;
            }
        } else {
            return false;
        }

    }

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

    /**
     * onFinishInflate 当View中所有的子控件均被映射成xml后触发
     */
    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        mAutoBackView = getChildAt(0);
    }
    
}

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值