自定義的可縮放可移動的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中做其他操作
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章