自定义LinearLayout,触摸子控件1移动父控件,触摸子控件2让父控件长度改变 2

之前1 写了很多都删了,2完善了一下,保留思路,

1.三个构造函数,获取了宽高 

  public DragScaleLinearLayout(Context context) {
        this(context, null);
    }

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

    public DragScaleLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        DisplayMetrics dm = getResources().getDisplayMetrics();
        screenWidth = dm.widthPixels;
        screenHeight = dm.heightPixels;
        // init();
    }

2.有些方法都没动

onMeasure,onLayout,dispatchTouchEvent

3.之前onTouch里判断触摸点是否在view范围内的方法出错了,替换为

   // 判断触摸点是否在View的范围内的方法
    private boolean isTouchInsideView(View view, float x, float y) {
        // 创建一个Rect对象,表示View在屏幕中的矩形区域
        Rect rect = new Rect();
        view.getGlobalVisibleRect(rect);

        // 判断触摸点是否在矩形区域内
        return rect.contains((int) x, (int) y);
    }

下面是之前的检测是否在view范围的方法

 /**
     * 计算指定的 View 在屏幕中的坐标。
     * 注意这个值是要从屏幕顶端算起,也就是索包括了通知栏的高度
     * location[0] x坐标
     * location[1] y坐标
     * view.getWidth(),  到父布局宽度的位置
     * 重点: 旋转后 View.getLocationOnScreen() 等返回的 View 的位置坐标还是以 View 原先左上角返回的旋转后的坐标值
     * 这个方法不知道为什么不行了,换成了 isTouchInsideView
     */
    public static RectF calcViewScreenLocation(View view) {
        int[] location = new int[2];
        //        获取当前焦点所在屏幕中的位置 view.getLocationOnScreen(location)
        // 获取控件在屏幕中的位置,返回的数组分别为控件左顶点的 x、y 的值
        view.getLocationOnScreen(location);
        return new RectF(location[0], location[1], location[0] + view.getWidth(),
                location[1] + view.getHeight());
    }

    // * 这个方法不知道为什么不行了,换成了 isTouchInsideView
    public static RectF calcViewScreenLocation2(View view) {
        int[] location = new int[2];
        //        获取当前焦点所在屏幕中的位置 view.getLocationOnScreen(location)
        // 获取控件在屏幕中的位置,返回的数组分别为控件左顶点的 x、y 的值
        view.getLocationOnScreen(location);
        return new RectF(location[0] - view.getWidth(), location[1], location[0],
                location[1] + view.getHeight());
    }

4.onTouchEvent 方法

  @Override
    public boolean onTouchEvent(MotionEvent ev) {
        int action = ev.getAction();

        switch (action) {
            case MotionEvent.ACTION_DOWN:
                lastX = ev.getRawX();//设定移动的初始位置相对位置
                lastY = ev.getRawY();
                // 触摸 iv_move 移动
//                RectF rect = calcViewScreenLocation2(ivMove);
//                mMove = rect.contains(lastX, lastY);
                mMove = isTouchInsideView(ivMove, lastX, lastY);
//                RectF rect2 = calcViewScreenLocation2(ivResize);
//                isInViewRect = rect2.contains(lastX, lastY);
                isInViewRect = isTouchInsideView(ivResize, lastX, lastY);
                Log.e(TAG, "onTouchEvent: " + mMove + "___" + isInViewRect);
                break;
            case MotionEvent.ACTION_MOVE:
                //移动//移动的距离X
                float dx = ev.getRawX() - lastX;
                float dy = ev.getRawY() - lastY;
                if (!isInViewRect && mMove) {
                    moveView((int) dx, (int) dy);
                } else {
                    //放大缩小 params.width =-1 //源码里看下就知道了。。 -1不代表宽度,代表MATCH_PARENT常量的值
                    ConstraintLayout.LayoutParams params = (ConstraintLayout.LayoutParams) getLayoutParams();
                    if (rotation) {
                        params.height = (int) Math.max(params.height - dx, 400);
                        params.width = (int) Math.max(getWidth() + dy, 400);
                    } else {
                        params.height = (int) Math.max(params.height + dy, 400);
                        params.width = (int) Math.max(getWidth() + dx, 400);
                    }
                    setLayoutParams(params);
                }
                lastX = (int) ev.getRawX();
                lastY = (int) ev.getRawY();
                break;
            case MotionEvent.ACTION_UP:
                requestLayout();
                break;
            default:
                break;
        }
        return isInViewRect ? isInViewRect : mMove;
    }

5.下面是move方法

private void moveView(int dx, int dy) {
        //设置控件的新位置  移动
        //  this.layout(left, top, right, bottom);
        //再次将滑动其实位置定位
        //理论中X轴拖动的距离
        float endX = getX() + dx;
        //理论中Y轴拖动的距离
        float endY = getY() + dy;
        //X轴可以拖动的最大距离
        float maxX = mRootMeasuredWidth - getWidth();
        //Y轴可以拖动的最大距离
        float maxY = mRootMeasuredHeight - getHeight();
        //X轴边界限制
        endX = endX < 0 ? 0 : Math.min(endX, maxX);
        //Y轴边界限制
        endY = endY < 0 ? 0 : Math.min(endY, maxY);

        setX(endX);
        setY(endY);
    }

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值