Android实现随意拖动View+ViewGroup效果(亲验可行)

·  阅读 1258

由于现在做一个拖拽效果的实现,发现网上的例子只有 View 的拖拽,但是没有 ViewGroup 的拖拽,为了回报社区,我也分享一下这两个效果!!

View的拖拽

代码如下,如果是View 主要是处理他的View 的触摸时间,然后 layout 重新摆放位置即可

 @Override
    public boolean onTouchEvent(MotionEvent event) {
        super.onTouchEvent(event);
        if (this.isEnabled()) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    isDrag = false;
                    downX = event.getX();
                    downY = event.getY();
                    break;
                case MotionEvent.ACTION_MOVE:
                    Log.e("kid", "ACTION_MOVE");
                    final float xDistance = event.getX() - downX;
                    final float yDistance = event.getY() - downY;
                    int l, r, t, b;
                    //当水平或者垂直滑动距离大于10,才算拖动事件
                    if (Math.abs(xDistance) > 10 || Math.abs(yDistance) > 10) {
                        Log.e("kid", "Drag");
                        isDrag = true;
                        l = (int) (getLeft() + xDistance);
                        r = l + width;
                        t = (int) (getTop() + yDistance);
                        b = t + height;
                        //不划出边界判断,此处应按照项目实际情况,因为本项目需求移动的位置是手机全屏,
                        // 所以才能这么写,如果是固定区域,要得到父控件的宽高位置后再做处理
                        if (l < 0) {
                            l = 0;
                            r = l + width;
                        } else if (r > screenWidth) {
                            r = screenWidth;
                            l = r - width;
                        }
                        if (t < 0) {
                            t = 0;
                            b = t + height;
                        } else if (b > screenHeight) {
                            b = screenHeight;
                            t = b - height;
                        }

                        this.layout(l, t, r, b);
                    }
                    break;
                case MotionEvent.ACTION_UP:
                    setPressed(false);
                    break;
                case MotionEvent.ACTION_CANCEL:
                    setPressed(false);
                    break;
            }
            return true;
        }
        return false;
    }
    
复制代码

ViewGroup 的拖拽

如果是ViewGroup 的话,需要处理分发的事件 当时遇到的问题如下

  1. 如果子View 处理的setonClick 会有问题

2.如果父控件有别的时间,如要 requestDisallowInterceptTouchEvent

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {

        getParent().requestDisallowInterceptTouchEvent(true);
        
        Boolean flag = handleEvent(event);

        if (flag) {
            return true;
        } else {
            return super.dispatchTouchEvent(event);
        }
    }
    
     @Nullable
    private Boolean handleEvent(MotionEvent event) {
        boolean result = false;
        if (this.isEnabled()) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    isDrag = false;
                    downX = event.getX();
                    downY = event.getY();
                    break;
                case MotionEvent.ACTION_MOVE:
                    Log.d(TAG, "====>>>   ACTION_MOVE");
                    final float xDistance = event.getX() - downX;
                    final float yDistance = event.getY() - downY;
                    int l, r, t, b;
                    //当水平或者垂直滑动距离大于10,才算拖动事件
                    if (Math.abs(xDistance) > scaledTouchSlop || Math.abs(yDistance) > scaledTouchSlop) {
                        Log.d(TAG, "====>>>   Drag: ");
                        isDrag = true;
                        l = (int) (getLeft() + xDistance);
                        r = l + width;
                        t = (int) (getTop() + yDistance);
                        b = t + height;
                        //不划出边界判断,此处应按照项目实际情况,因为本项目需求移动的位置是手机全屏,
                        // 所以才能这么写,如果是固定区域,要得到父控件的宽高位置后再做处理
                        if (l < 0) {
                            l = 0;
                            r = l + width;
                        } else if (r > screenWidth) {
                            r = screenWidth;
                            l = r - width;
                        }
                        if (t < 0) {
                            t = 0;
                            b = t + height;
                        } else if (b > screenHeight) {
                            b = screenHeight;
                            t = b - height;
                        }

                        this.layout(l, t, r, b);
                    }
                    break;
                case MotionEvent.ACTION_UP:
                case MotionEvent.ACTION_CANCEL:

                    break;
            }
        }
        return isDrag;
    }
复制代码

完整代码获取方式如下:

  1. 关注的公众号:苍溟
  2. 输入关键词: 拖动View
分类:
Android
标签: