Android可以拖动缩放的相对布局

一个可以拖动,缩放的相对布局,真正写起来还是很简单的。
public class MoveZoomRelativeLayout extends RelativeLayout {

    //event.actiondown发生的坐标
    private float oldX;
    private float oldY;
    //布局的宽高
    private int mwidth;
    private int mheight;
    //触摸模式
    private int TOUCHMODE = 0;
    private int DRAGMODE = 0;
    private int ZOOMMODE = 1;
    //布局各边到绝对坐标系的距离
    private int left;
    private int right;
    private int top;
    private int bottom;

    //上次移动事件发生的坐标
    private float premoveX;
    private float premoveY;
    private float oldrawX;
    private float oldrawY;

    //接口对象
    private GetSizeInterface getsizeinterface;

    private Context context;

    //是否禁止触摸
    private boolean disallowtouch;
    private int screenwidth;
    private int screenheight;

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

    public MoveZoomRelativeLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        init();
    }

    private void init() {
        //获取屏幕的宽高
        DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
        screenwidth = displayMetrics.widthPixels;
        screenheight = displayMetrics.heightPixels;
        //获取布局的宽高
//        int width = getWidth();
//        int height = getHeight();
//        int left = (widthPixels - width) / 2;
//        int top = (heightPixels - height) / 2;
//        LayoutParams layoutParams = (LayoutParams) getLayoutParams();
//        layoutParams.setMargins(left,top,left + width, top + height);
//        setLayoutParams(layoutParams);
//        layout(left, top, left + width, top + height);
    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (!disallowtouch) {
            mwidth = getWidth();
            mheight = getHeight();
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    oldX = event.getX();
                    oldrawX = event.getRawX();
                    oldY = event.getY();
                    oldrawY = event.getRawY();
                    //设置布局的中间长宽各80%的区域为可移动区域,其余部分为可拉伸区域。
                    if (oldX < mwidth * 0.2 || oldX > mwidth * 0.8 || oldY < mheight * 0.2 || oldY > mheight * 0.8) {
                        TOUCHMODE = ZOOMMODE;
                    } else {
                        TOUCHMODE = DRAGMODE;
                    }
                    left = getLeft();
                    right = getRight();
                    top = getTop();
                    bottom = getBottom();
                    break;
                case MotionEvent.ACTION_MOVE:
                    if (TOUCHMODE == DRAGMODE) {
                        float neweventX = event.getX();
                        float neweventY = event.getY();
                        int moveX = ((int) (neweventX - oldX));
                        int moveY = ((int) (neweventY - oldY));
                        Log.i(TAG, "onTouchEvent: drag" + moveX + ";" + moveY);
                        //该方法移动view,弹出输入法就会导致位置复原
//                        layout(getLeft() + moveX, getTop() + moveY, getRight() + moveX, getBottom() + moveY);
                        LayoutParams layoutParams = (LayoutParams) getLayoutParams();
                        layoutParams.setMargins(getLeft() + moveX, getTop() + moveY, 0, 0);
                        setLayoutParams(layoutParams);
                        left = getLeft();
                        right = getRight();
                        top = getTop();
                        bottom = getBottom();
                    }
                    if (TOUCHMODE == ZOOMMODE) {
                        float newrawX = event.getRawX();
                        float newrawY = event.getRawY();
                        //注释掉的方法应该也是可行的,但是未测试了
//                    float neweventX = event.getX();
//                    float neweventY = event.getY();
//                    if (premoveX == 0 && premoveY == 0) {
//                        int moveX = (int) (neweventX - oldX);
//                        int moveY = (int) (neweventY - oldY);
//                        Log.i(TAG, "onTouchEvent: 0zoom" + moveX + ";" + moveY);
//                        LayoutParams layoutParams = (LayoutParams) getLayoutParams();
//                        layoutParams.width = mwidth + moveX;
//                        layoutParams.height = mheight + moveY;
//                        setLayoutParams(layoutParams);
//                        layout(left, top, right, bottom);
//                        premoveX = neweventX;
//                        premoveY = neweventY;

                        if (premoveX == 0 && premoveY == 0) 
                   //这里判断premoveX和premoveY来选择使用哪种方式计算缩放大小是因为,oldrawX和oldrawY
                   //只会在触发down时改变,所以连续滑动时这2个值是不准确的导致缩放的速度越来越快
int moveX = (int) (newrawX - oldrawX); int moveY = (int) (newrawY - oldrawY); Log.i(TAG, "onTouchEvent: 0zoom" + moveX + ";" + moveY); LayoutParams layoutParams = (LayoutParams) getLayoutParams();
                //这里的判断有点问题,因为都是且判断,所以导致宽或者高不满足另外一者也不能改变
                //当2个都不满足时(其实很难哦),只改变一者也无法改变布局了,但由于判断的是计算之后的大小
                //是否符合条件,因此不会卡死.
                       if (mwidth + moveX > screenwidth * 0.2 && mwidth + moveX < screenwidth * 0.8 && mheight + moveY > screenheight * 0.2 && mheight + moveY < screenheight * 0.8) { layoutParams.width = mwidth + moveX; layoutParams.height = mheight + moveY; layoutParams.setMargins(getLeft(), getTop(), 0, 0); setLayoutParams(layoutParams);// layout(left, top, right, bottom); premoveX = newrawX; premoveY = newrawY; getsizeinterface.getSize(layoutParams.width, layoutParams.height); } } else { //注释掉的方法应该也是可行的,但是未测试了// int moveX = (int) (neweventX - premoveX);// int moveY = (int) (neweventY - premoveY);// Log.i(TAG, "onTouchEvent: zoom" + moveX + ";" + moveY);// LayoutParams layoutParams = (LayoutParams) getLayoutParams();// layoutParams.width = mwidth + moveX;// layoutParams.height = mheight + moveY;// setLayoutParams(layoutParams);// layout(left, top, right, bottom);// premoveX = neweventX;// premoveY = neweventY; int moveX = (int) (newrawX - premoveX); int moveY = (int) (newrawY - premoveY); Log.i(TAG, "onTouchEvent: zoom" + moveX + ";" + moveY); LayoutParams layoutParams = (LayoutParams) getLayoutParams(); if (mwidth + moveX > screenwidth * 0.2 && mwidth < screenwidth * 0.8 && mheight + moveY > screenheight * 0.2 && mheight + moveY < screenheight * 0.8) { layoutParams.width = mwidth + moveX; layoutParams.height = mheight + moveY; layoutParams.setMargins(layoutParams.leftMargin, layoutParams.topMargin, 0, 0); setLayoutParams(layoutParams);// layout(left, top, right, bottom); premoveX = newrawX; premoveY = newrawY; getsizeinterface.getSize(layoutParams.width, layoutParams.height); } } } break; case MotionEvent.ACTION_UP: premoveY = 0; premoveX = 0; break; default: break; } return true; } return false; } @Override public void onWindowFocusChanged(boolean hasWindowFocus) { if (hasWindowFocus) { } } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { return false; } //通过该接口实时的把布局的宽高传递出去 public interface GetSizeInterface { void getSize(int width, int height); } public void setInterface(GetSizeInterface getsizeinterface) { this.getsizeinterface = getsizeinterface; } public void setdisallowtouch(boolean b) { this.disallowtouch = b; }}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值