自定义的可缩放可移动的layout

自定义的可缩放可移动的layout

/**
 * 可缩放,可移动的Layout
 * @author fengzhiqi
 * @since 2017-8/24
 */
public class PowerfulLayout extends FrameLayout {
    // 屏幕宽高
    private int screenHeight;
    private int screenWidth;
    private ViewDragHelper mDragHelper;
    private long lastMultiTouchTime;// 记录多点触控缩放后的时间
    private ScaleGestureDetector mScaleGestureDetector = null;
    // private View view;
    private int downX;//手指按下的x坐标值
    private int downY;//手指按下的y坐标值
    private boolean needToHandle=true;
    private int moveX;
    private int moveY;
    private float scale;//缩放比例
    private float preScale = 1f;// 默认前一次缩放比例为1

    public PowerfulLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    public PowerfulLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public PowerfulLayout(Context context) {
        super(context);
        init(context);
    }

    private void init(Context context) {
        mDragHelper = ViewDragHelper.create(this, callback);
        mScaleGestureDetector = new ScaleGestureDetector(context,
                new ScaleGestureListener());
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        screenWidth = getMeasuredWidth();
        screenHeight = getMeasuredHeight();
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        super.onInterceptTouchEvent(ev);
        boolean b = mDragHelper.shouldInterceptTouchEvent(ev);// 由mDragHelper决定是否拦截事件,并传递给onTouchEvent
        return b;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        int pointerCount = event.getPointerCount(); // 获得多少点
        if (pointerCount > 1) {// 多点触控,
            switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                needToHandle=false;
                break;
            case MotionEvent.ACTION_MOVE:
                break;
            case MotionEvent.ACTION_POINTER_2_UP://第二个手指抬起的时候
                lastMultiTouchTime = System.currentTimeMillis();
                needToHandle=true;
                break;
            default:
                break;
            }
            return mScaleGestureDetector.onTouchEvent(event);//让mScaleGestureDetector处理触摸事件
        } else {
            //在500ms后解锁控件的左右滑动
            //防止缩放后控件乱动
            long currentTimeMillis = System.currentTimeMillis();
            if ( currentTimeMillis - lastMultiTouchTime > 500&&needToHandle){
                switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    downX = (int)event.getX();
                    downY = (int)event.getY();
                    break;
                case MotionEvent.ACTION_MOVE:
                    Log.e("fzq", "------move");
                    moveX = (int) event.getX();
                    moveY = (int) event.getY(); 
                    scrollBy(downX-moveX, downY-moveY);
                    downX = moveX;
                    downY = moveY;
                default:
                    break;
                }
                return true;
            }
        }
        return false;
    }

    private ViewDragHelper.Callback callback = new ViewDragHelper.Callback() {
        /**
         * 用于判断是否捕获当前child的触摸事件
         * 
         * @param child
         *            当前触摸的子view
         * @param pointerId
         * @return true就捕获并解析;false不捕获
         */
        @Override
        public boolean tryCaptureView(View child, int pointerId) {
            if (preScale > 1.5)
                return true;
            return false;
        }

        /**
         * 控制水平方向上的位置
         */
        @Override
        public int clampViewPositionHorizontal(View child, int left, int dx) {

            if (left < (screenWidth - screenWidth * preScale) / 2)
                left = (int) (screenWidth - screenWidth * preScale) / 2;// 限制mainView可向左移动到的位置
            if (left > (screenWidth * preScale - screenWidth) / 2)
                left = (int) (screenWidth * preScale - screenWidth) / 2;// 限制mainView可向右移动到的位置
            return left;
        }

        public int clampViewPositionVertical(View child, int top, int dy) {

            if (top < (screenHeight - screenHeight * preScale) / 2) {
                top = (int) (screenHeight - screenHeight * preScale) / 2;// 限制mainView可向上移动到的位置
            }
            if (top > (screenHeight * preScale - screenHeight) / 2) {
                top = (int) (screenHeight * preScale - screenHeight) / 2;// 限制mainView可向上移动到的位置
            }
            return top;
        }

    };

    public class ScaleGestureListener implements
            ScaleGestureDetector.OnScaleGestureListener {

        @Override
        public boolean onScale(ScaleGestureDetector detector) {

            float previousSpan = detector.getPreviousSpan();// 前一次双指间距
            float currentSpan = detector.getCurrentSpan();// 本次双指间距
            if (currentSpan < previousSpan) {
                // 缩小
                scale = preScale - (previousSpan - currentSpan) / 1000;
            } else {
                // 放大
                scale = preScale + (currentSpan - previousSpan) / 1000;
            }
            // 缩放view
            if (scale>0.5 && scale<1.5) {
                for (int i = 0; i < getChildCount(); i++) {
                    getChildAt(i).setScaleX(scale);
                    getChildAt(i).setScaleY(scale);
//                  lastMultiTouchTime = System.currentTimeMillis();
                }
            }
            return false;
        }

        @Override
        public boolean onScaleBegin(ScaleGestureDetector detector) {
            // 一定要返回true才会进入onScale()这个函数
            return true;
        }

        @Override
        public void onScaleEnd(ScaleGestureDetector detector) {
            preScale = scale;// 记录本次缩放比例
            lastMultiTouchTime = System.currentTimeMillis();// 记录双指缩放后的时间
        }
    }

}



使用方法:
使用是直接使用,不用在Activity中做其他操作

猜你喜欢

转载自blog.csdn.net/fengzhiqi1993/article/details/77531253