Example usage for android.view ScaleGestureDetector getFocusY

List of usage examples for android.view ScaleGestureDetector getFocusY

Introduction

In this page you can find the example usage for android.view ScaleGestureDetector getFocusY.

Prototype

public float getFocusY() 

Source Link

Document

Get the Y coordinate of the current gesture's focal point.

Usage

From source file:com.apptentive.android.sdk.util.image.PreviewImageView.java

@Override
public boolean onScale(ScaleGestureDetector detector) {
    float scale = getScale();
    float scaleFactor = detector.getScaleFactor();

    if (getDrawable() == null)
        return true;

    /**/*from www  .  j av a  2s. co m*/
     * Scale range check
     */
    if ((scale < SCALE_MAX && scaleFactor > 1.0f) || (scale >= initScale && scaleFactor < 1.0f)) {

        if (scaleFactor * scale < initScale) {
            scaleFactor = initScale / scale;
        }
        if (scaleFactor * scale > SCALE_MAX) {
            scaleFactor = SCALE_MAX / scale;
        }
        /**
         * Set scaling into matrix
         */
        scaleMatrix.postScale(scaleFactor, scaleFactor, detector.getFocusX(), detector.getFocusY());
        checkBorderAndCenterWhenScale();
        setImageMatrix(scaleMatrix);
    }
    return true;

}

From source file:com.mediatek.galleryfeature.stereo.segment.ImageShow.java

@Override
public boolean onScale(ScaleGestureDetector detector) {
    if (!mIsZoomPanSupported) {
        return false;
    }/*from   ww  w  .ja  v a 2s. c  om*/
    float scaleFactor = mMasterImage.getScaleFactor();

    scaleFactor = scaleFactor * detector.getScaleFactor();
    if (scaleFactor > mMasterImage.getMaxScaleFactor()) {
        scaleFactor = mMasterImage.getMaxScaleFactor();
    }
    if (scaleFactor < 1.0f) {
        scaleFactor = 1.0f;
    }
    mMasterImage.setScaleFactor(scaleFactor);
    scaleFactor = mMasterImage.getScaleFactor();
    float focusx = detector.getFocusX();
    float focusy = detector.getFocusY();
    float translateX = (focusx - mStartFocusX) / scaleFactor;
    float translateY = (focusy - mStartFocusY) / scaleFactor;
    Point translation = mMasterImage.getTranslation();
    translation.x = (int) (mOriginalTranslation.x + translateX);
    translation.y = (int) (mOriginalTranslation.y + translateY);
    mMasterImage.setTranslation(translation);
    invalidate();
    return true;
}

From source file:com.android.gallery3d.filtershow.imageshow.ImageShow.java

@Override
public boolean onScaleBegin(ScaleGestureDetector detector) {
    Point pos = MasterImage.getImage().getTranslation();
    mOriginalTranslation.x = pos.x;// w ww.  ja v a2 s  . c  o m
    mOriginalTranslation.y = pos.y;
    mOriginalScale = MasterImage.getImage().getScaleFactor();
    mStartFocusX = detector.getFocusX();
    mStartFocusY = detector.getFocusY();
    mInteractionMode = InteractionMode.SCALE;
    return true;
}

From source file:com.diegocarloslima.byakugallery.TouchImageView.java

public TouchImageView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);

    if (ANIMATION_DURATION == 0)
        ANIMATION_DURATION = context.getResources().getInteger(android.R.integer.config_shortAnimTime);

    final TouchGestureDetector.OnTouchGestureListener listener = new TouchGestureDetector.OnTouchGestureListener() {

        @Override//from   ww  w  .  j  ava2 s . c om
        public boolean onSingleTapConfirmed(MotionEvent e) {
            return performClick();
        }

        @Override
        public void onLongPress(MotionEvent e) {
            performLongClick();
        }

        @Override
        public boolean onDoubleTap(MotionEvent e) {
            loadMatrixValues();

            // 3 stage scaling
            float targetScale = mCropScale;
            if (mScale == mMaxScale)
                targetScale = mMinScale;
            else if (mScale >= mCropScale)
                targetScale = mMaxScale;

            // First, we try to keep the focused point in the same position when the animation ends
            final float desiredTranslationX = e.getX() - (e.getX() - mTranslationX) * (targetScale / mScale);
            final float desiredTranslationY = e.getY() - (e.getY() - mTranslationY) * (targetScale / mScale);

            // Here, we apply a correction to avoid unwanted blank spaces
            final float targetTranslationX = desiredTranslationX + computeTranslation(getMeasuredWidth(),
                    mDrawableIntrinsicWidth * targetScale, desiredTranslationX, 0);
            final float targetTranslationY = desiredTranslationY + computeTranslation(getMeasuredHeight(),
                    mDrawableIntrinsicHeight * targetScale, desiredTranslationY, 0);

            clearAnimation();
            final Animation animation = new TouchAnimation(targetScale, targetTranslationX, targetTranslationY);
            animation.setDuration(ANIMATION_DURATION);
            startAnimation(animation);

            return true;
        }

        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
            // Sometimes, this method is called just after an onScaleEnd event. In this case, we want to wait until we animate back our image
            if (mIsAnimatingBack) {
                return false;
            }

            loadMatrixValues();

            final float currentDrawableWidth = mDrawableIntrinsicWidth * mScale;
            final float currentDrawableHeight = mDrawableIntrinsicHeight * mScale;

            final float dx = computeTranslation(getMeasuredWidth(), currentDrawableWidth, mTranslationX,
                    -distanceX);
            final float dy = computeTranslation(getMeasuredHeight(), currentDrawableHeight, mTranslationY,
                    -distanceY);
            mMatrix.postTranslate(dx, dy);

            clearAnimation();
            ViewCompat.postInvalidateOnAnimation(TouchImageView.this);

            return true;
        }

        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            // Sometimes, this method is called just after an onScaleEnd event. In this case, we want to wait until we animate back our image
            if (mIsAnimatingBack) {
                return false;
            }

            loadMatrixValues();

            final float horizontalSideFreeSpace = (getMeasuredWidth() - mDrawableIntrinsicWidth * mScale) / 2F;
            final float minTranslationX = horizontalSideFreeSpace > 0 ? horizontalSideFreeSpace
                    : getMeasuredWidth() - mDrawableIntrinsicWidth * mScale;
            final float maxTranslationX = horizontalSideFreeSpace > 0 ? horizontalSideFreeSpace : 0;

            final float verticalSideFreeSpace = (getMeasuredHeight() - mDrawableIntrinsicHeight * mScale) / 2F;
            final float minTranslationY = verticalSideFreeSpace > 0 ? verticalSideFreeSpace
                    : getMeasuredHeight() - mDrawableIntrinsicHeight * mScale;
            final float maxTranslationY = verticalSideFreeSpace > 0 ? verticalSideFreeSpace : 0;

            // Using FlingScroller here. The results were better than the Scroller class
            // https://android.googlesource.com/platform/packages/apps/Gallery2/+/master/src/com/android/gallery3d/ui/FlingScroller.java
            mFlingScroller.fling(Math.round(mTranslationX), Math.round(mTranslationY), Math.round(velocityX),
                    Math.round(velocityY), Math.round(minTranslationX), Math.round(maxTranslationX),
                    Math.round(minTranslationY), Math.round(maxTranslationY));

            clearAnimation();
            final Animation animation = new FlingAnimation();
            animation.setDuration(mFlingScroller.getDuration());
            animation.setInterpolator(new LinearInterpolator());
            startAnimation(animation);

            return true;
        }

        @Override
        public boolean onScaleBegin(ScaleGestureDetector detector) {
            mLastFocusX = null;
            mLastFocusY = null;

            return true;
        }

        @Override
        public boolean onScale(ScaleGestureDetector detector) {
            loadMatrixValues();

            float currentDrawableWidth = mDrawableIntrinsicWidth * mScale;
            float currentDrawableHeight = mDrawableIntrinsicHeight * mScale;

            final float focusX = computeFocus(getMeasuredWidth(), currentDrawableWidth, mTranslationX,
                    detector.getFocusX());
            final float focusY = computeFocus(getMeasuredHeight(), currentDrawableHeight, mTranslationY,
                    detector.getFocusY());

            // Here, we provide the ability to scroll while scaling
            if (mLastFocusX != null && mLastFocusY != null) {
                final float dx = computeScaleTranslation(getMeasuredWidth(), currentDrawableWidth,
                        mTranslationX, focusX - mLastFocusX);
                final float dy = computeScaleTranslation(getMeasuredHeight(), currentDrawableHeight,
                        mTranslationY, focusY - mLastFocusY);

                if (dx != 0 || dy != 0) {
                    mMatrix.postTranslate(dx, dy);
                }
            }

            final float scale = computeScale(mMinScale, mMaxScale, mScale, detector.getScaleFactor());
            mMatrix.postScale(scale, scale, focusX, focusY);

            mLastFocusX = focusX;
            mLastFocusY = focusY;

            clearAnimation();
            ViewCompat.postInvalidateOnAnimation(TouchImageView.this);

            return true;
        }

        @Override
        public void onScaleEnd(ScaleGestureDetector detector) {
            loadMatrixValues();

            final float currentDrawableWidth = mDrawableIntrinsicWidth * mScale;
            final float currentDrawableHeight = mDrawableIntrinsicHeight * mScale;

            final float dx = computeTranslation(getMeasuredWidth(), currentDrawableWidth, mTranslationX, 0);
            final float dy = computeTranslation(getMeasuredHeight(), currentDrawableHeight, mTranslationY, 0);

            if (Math.abs(dx) < 1 && Math.abs(dy) < 1) {
                return;
            }

            final float targetTranslationX = mTranslationX + dx;
            final float targetTranslationY = mTranslationY + dy;

            float targetScale = MathUtils.clamp(mScale, mMinScale, mMaxScale);

            clearAnimation();
            final Animation animation = new TouchAnimation(targetScale, targetTranslationX, targetTranslationY);
            animation.setDuration(ANIMATION_DURATION);
            startAnimation(animation);

            mIsAnimatingBack = true;
        }
    };

    mTouchGestureDetector = new TouchGestureDetector(context, listener);

    super.setScaleType(ScaleType.MATRIX);
}

From source file:org.mariotaku.twidere.view.TouchImageView.java

public TouchImageView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);

    final TouchGestureDetector.OnTouchGestureListener listener = new TouchGestureDetector.OnTouchGestureListener() {

        @Override//from  w w  w  .  j a va 2s . c o m
        public boolean onSingleTapConfirmed(MotionEvent e) {
            return performClick();
        }

        @Override
        public void onLongPress(MotionEvent e) {
            performLongClick();
        }

        @Override
        public boolean onDoubleTap(MotionEvent e) {
            loadMatrixValues();

            final float minScale = getMinScale();
            // If we have already zoomed in, we should return to our initial scale value (minScale). Otherwise, scale to full size
            final boolean shouldZoomOut = mScale > minScale;
            final float targetScale = shouldZoomOut ? minScale : mMaxScale;

            // First, we try to keep the focused point in the same position when the animation ends
            final float desiredTranslationX = e.getX() - (e.getX() - mTranslationX) * (targetScale / mScale);
            final float desiredTranslationY = e.getY() - (e.getY() - mTranslationY) * (targetScale / mScale);

            // Here, we apply a correction to avoid unwanted blank spaces
            final float targetTranslationX = desiredTranslationX + computeTranslation(getMeasuredWidth(),
                    mDrawableIntrinsicWidth * targetScale, desiredTranslationX, 0);
            final float targetTranslationY = desiredTranslationY + computeTranslation(getMeasuredHeight(),
                    mDrawableIntrinsicHeight * targetScale, desiredTranslationY, 0);

            clearAnimation();
            final Animation animation = new TouchAnimation(targetScale, targetTranslationX, targetTranslationY);
            animation.setDuration(DOUBLE_TAP_ANIMATION_DURATION);
            startAnimation(animation);

            if (mZoomListener != null) {
                if (shouldZoomOut) {
                    mZoomListener.onZoomOut();
                } else {
                    mZoomListener.onZoomIn();
                }
            }
            return true;
        }

        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
            // Sometimes, this method is called just after an onScaleEnd event. In this case, we want to wait until we animate back our image
            if (mIsAnimatingBack) {
                return false;
            }

            loadMatrixValues();

            final float currentDrawableWidth = mDrawableIntrinsicWidth * mScale;
            final float currentDrawableHeight = mDrawableIntrinsicHeight * mScale;

            final float dx = computeTranslation(getMeasuredWidth(), currentDrawableWidth, mTranslationX,
                    -distanceX);
            final float dy = computeTranslation(getMeasuredHeight(), currentDrawableHeight, mTranslationY,
                    -distanceY);
            mMatrix.postTranslate(dx, dy);

            clearAnimation();
            ViewCompat.postInvalidateOnAnimation(TouchImageView.this);

            return true;
        }

        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            // Sometimes, this method is called just after an onScaleEnd event. In this case, we want to wait until we animate back our image
            if (mIsAnimatingBack) {
                return false;
            }

            loadMatrixValues();

            final float horizontalSideFreeSpace = (getMeasuredWidth() - mDrawableIntrinsicWidth * mScale) / 2F;
            final float minTranslationX = horizontalSideFreeSpace > 0 ? horizontalSideFreeSpace
                    : getMeasuredWidth() - mDrawableIntrinsicWidth * mScale;
            final float maxTranslationX = horizontalSideFreeSpace > 0 ? horizontalSideFreeSpace : 0;

            final float verticalSideFreeSpace = (getMeasuredHeight() - mDrawableIntrinsicHeight * mScale) / 2F;
            final float minTranslationY = verticalSideFreeSpace > 0 ? verticalSideFreeSpace
                    : getMeasuredHeight() - mDrawableIntrinsicHeight * mScale;
            final float maxTranslationY = verticalSideFreeSpace > 0 ? verticalSideFreeSpace : 0;

            // Using FlingScroller here. The results were better than the Scroller class
            // https://android.googlesource.com/platform/packages/apps/Gallery2/+/master/src/com/android/gallery3d/ui/FlingScroller.java
            mFlingScroller.fling(Math.round(mTranslationX), Math.round(mTranslationY), Math.round(velocityX),
                    Math.round(velocityY), Math.round(minTranslationX), Math.round(maxTranslationX),
                    Math.round(minTranslationY), Math.round(maxTranslationY));

            clearAnimation();
            final Animation animation = new FlingAnimation();
            animation.setDuration(mFlingScroller.getDuration());
            animation.setInterpolator(new LinearInterpolator());
            startAnimation(animation);

            return true;
        }

        @Override
        public boolean onScaleBegin(ScaleGestureDetector detector) {
            mLastFocusX = null;
            mLastFocusY = null;

            return true;
        }

        @Override
        public boolean onScale(ScaleGestureDetector detector) {
            loadMatrixValues();

            float currentDrawableWidth = mDrawableIntrinsicWidth * mScale;
            float currentDrawableHeight = mDrawableIntrinsicHeight * mScale;

            final float focusX = computeFocus(getMeasuredWidth(), currentDrawableWidth, mTranslationX,
                    detector.getFocusX());
            final float focusY = computeFocus(getMeasuredHeight(), currentDrawableHeight, mTranslationY,
                    detector.getFocusY());

            // Here, we provide the ability to scroll while scaling
            if (mLastFocusX != null && mLastFocusY != null) {
                final float dx = computeScaleTranslation(getMeasuredWidth(), currentDrawableWidth,
                        mTranslationX, focusX - mLastFocusX);
                final float dy = computeScaleTranslation(getMeasuredHeight(), currentDrawableHeight,
                        mTranslationY, focusY - mLastFocusY);

                if (dx != 0 || dy != 0) {
                    mMatrix.postTranslate(dx, dy);
                }
            }

            final float scale = computeScale(getMinScale(), mMaxScale, mScale, detector.getScaleFactor());
            mMatrix.postScale(scale, scale, focusX, focusY);

            mLastFocusX = focusX;
            mLastFocusY = focusY;

            clearAnimation();
            ViewCompat.postInvalidateOnAnimation(TouchImageView.this);

            return true;
        }

        @Override
        public void onScaleEnd(ScaleGestureDetector detector) {
            loadMatrixValues();

            final float currentDrawableWidth = mDrawableIntrinsicWidth * mScale;
            final float currentDrawableHeight = mDrawableIntrinsicHeight * mScale;

            final float dx = computeTranslation(getMeasuredWidth(), currentDrawableWidth, mTranslationX, 0);
            final float dy = computeTranslation(getMeasuredHeight(), currentDrawableHeight, mTranslationY, 0);

            if (Math.abs(dx) < 1 && Math.abs(dy) < 1) {
                return;
            }

            final float targetTranslationX = mTranslationX + dx;
            final float targetTranslationY = mTranslationY + dy;

            clearAnimation();
            final Animation animation = new TouchAnimation(mScale, targetTranslationX, targetTranslationY);
            animation.setDuration(SCALE_END_ANIMATION_DURATION);
            startAnimation(animation);

            mIsAnimatingBack = true;
        }
    };

    mTouchGestureDetector = new TouchGestureDetector(context, listener);

    super.setScaleType(ScaleType.MATRIX);
}

From source file:com.example.nitish.welcomapp.widgetpt.PeriodicTableView.java

/**
 * Create the listener for the ScaleGestureDetector.
 *
 * @return The OnScaleGestureListener//www .  j  ava 2s .  c  om
 */
@NonNull
private ScaleGestureDetector.OnScaleGestureListener getOnScaleGestureListener() {
    return new ScaleGestureDetector.SimpleOnScaleGestureListener() {
        /**
         * The initial span of the scale gesture
         */
        private float mStartSpan;

        @Override
        public boolean onScaleBegin(ScaleGestureDetector detector) {
            clearSelection();
            mScaleRect.set(mContentRect);
            mStartSpan = detector.getCurrentSpan();

            return true;
        }

        @Override
        public boolean onScale(ScaleGestureDetector detector) {
            mScaleFocalPoint.set(detector.getFocusX() / getWidth(), detector.getFocusY() / getHeight());
            setZoom(mCurrentZoom
                    + mCurrentZoom * (detector.getCurrentSpan() - detector.getPreviousSpan()) / mStartSpan);

            return true;
        }

        @Override
        public void onScaleEnd(ScaleGestureDetector detector) {
            if (mPeriodicTableListener != null) {
                mPeriodicTableListener.onZoomEnd(PeriodicTableView.this);
            }
        }
    };
}

From source file:com.ultramegatech.ey.widget.PeriodicTableView.java

/**
 * Create the listener for the ScaleGestureDetector.
 *
 * @return The OnScaleGestureListener/*from  w w w  . j a  v a 2s .  c  o m*/
 */
@NonNull
private ScaleGestureDetector.OnScaleGestureListener getOnScaleGestureListener() {
    //noinspection MethodDoesntCallSuperMethod
    return new ScaleGestureDetector.SimpleOnScaleGestureListener() {
        /**
         * The initial span of the scale gesture
         */
        private float mStartSpan;

        @Override
        public boolean onScaleBegin(ScaleGestureDetector detector) {
            clearSelection();
            mScaleRect.set(mContentRect);
            mStartSpan = detector.getCurrentSpan();

            return true;
        }

        @Override
        public boolean onScale(ScaleGestureDetector detector) {
            mScaleFocalPoint.set(detector.getFocusX() / getWidth(), detector.getFocusY() / getHeight());
            setZoom(mCurrentZoom
                    + mCurrentZoom * (detector.getCurrentSpan() - detector.getPreviousSpan()) / mStartSpan);

            return true;
        }

        @Override
        public void onScaleEnd(ScaleGestureDetector detector) {
            if (mPeriodicTableListener != null) {
                mPeriodicTableListener.onZoomEnd(PeriodicTableView.this);
            }
        }
    };
}

From source file:com.android.gallery3d.filtershow.imageshow.ImageShow.java

@Override
public boolean onScale(ScaleGestureDetector detector) {
    MasterImage img = MasterImage.getImage();
    float scaleFactor = img.getScaleFactor();

    scaleFactor = scaleFactor * detector.getScaleFactor();
    if (scaleFactor > MasterImage.getImage().getMaxScaleFactor()) {
        scaleFactor = MasterImage.getImage().getMaxScaleFactor();
    }//  w  w  w  . ja v  a  2s  .  com
    if (scaleFactor < 1.0f) {
        scaleFactor = 1.0f;
    }
    MasterImage.getImage().setScaleFactor(scaleFactor);
    scaleFactor = img.getScaleFactor();
    float focusx = detector.getFocusX();
    float focusy = detector.getFocusY();
    float translateX = (focusx - mStartFocusX) / scaleFactor;
    float translateY = (focusy - mStartFocusY) / scaleFactor;
    Point translation = MasterImage.getImage().getTranslation();
    translation.x = (int) (mOriginalTranslation.x + translateX);
    translation.y = (int) (mOriginalTranslation.y + translateY);
    MasterImage.getImage().setTranslation(translation);
    invalidate();
    return true;
}

From source file:com.appunite.scroll.ScaleImageView.java

@SuppressWarnings("UnusedDeclaration")
public ScaleImageView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);

    final ViewConfiguration viewConfiguration = ViewConfiguration.get(context);
    mMinEdge = viewConfiguration.getScaledEdgeSlop();

    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ScaleImageView, defStyle, defStyle);
    assert a != null;

    Drawable src = null;//from  ww  w . ja  v  a2  s  .  c o m
    try {
        mMinWidth = a.getDimensionPixelSize(R.styleable.ScaleImageView_android_minWidth, 0);
        mMinHeight = a.getDimensionPixelSize(R.styleable.ScaleImageView_android_minHeight, 0);
        src = a.getDrawable(R.styleable.ScaleImageView_android_src);
    } finally {
        a.recycle();
    }

    ScaleGestureDetector.OnScaleGestureListener scaleGestureListener = new ScaleGestureDetector.SimpleOnScaleGestureListener() {
        /**
         * This is the active focal point in terms of the viewport. Could be a local
         * variable but kept here to minimize per-frame allocations.
         */
        private PointF viewportFocus = new PointF();

        @Override
        public boolean onScaleBegin(ScaleGestureDetector scaleGestureDetector) {
            final ViewParent parent = getParent();
            if (parent != null) {
                parent.requestDisallowInterceptTouchEvent(true);
            }
            return true;
        }

        @Override
        public boolean onScale(ScaleGestureDetector scaleGestureDetector) {
            float focusX = scaleGestureDetector.getFocusX();
            float focusY = scaleGestureDetector.getFocusY();
            float scaleFactor = scaleGestureDetector.getScaleFactor();
            float previousScale = mScale;
            mScale *= scaleFactor;

            doScale(focusX, focusY, scaleFactor);
            return true;
        }

    };
    GestureDetector.SimpleOnGestureListener gestureListener = new GestureDetector.SimpleOnGestureListener() {
        @Override
        public boolean onDown(MotionEvent e) {

            releaseEdgeEffects();
            mScroller.forceFinished(true);
            ViewCompat.postInvalidateOnAnimation(ScaleImageView.this);
            return true;
        }

        @Override
        public boolean onSingleTapConfirmed(MotionEvent e) {
            return performClick();
        }

        @Override
        public boolean onDoubleTap(MotionEvent e) {
            mZoomer.forceFinished(true);
            mZoomStartScale = mScale;
            mZoomFocalPoint.set(e.getX(), e.getY());
            mZoomer.startZoom(ZOOM_AMOUNT);
            ViewCompat.postInvalidateOnAnimation(ScaleImageView.this);
            return true;
        }

        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
            getRealTranslation(mTranslation, mRealTranslation);
            mRealTranslation.offset(-distanceX, -distanceY);
            getTranslation(mRealTranslation, mTranslation);

            computeMaxScrollSize(mMaxScrollBuffer);
            getImageRect(mRectF);
            float scrolledX = -mRectF.left;
            float scrolledY = -mRectF.top;
            boolean canScrollX = mRectF.left > mContentRect.left || mRectF.right < mContentRect.right;
            boolean canScrollY = mRectF.top > mContentRect.top || mRectF.bottom < mContentRect.bottom;
            validateTranslation();

            disallowParentInterceptWhenOnEdge(distanceX, distanceY);

            if (mScale > mMinScale) {
                if (canScrollX && scrolledX < 0) {
                    mEdgeEffectLeft.onPull(scrolledX / (float) mContentRect.width());
                    mEdgeEffectLeftActive = true;
                }
                if (canScrollY && scrolledY < 0) {
                    mEdgeEffectTop.onPull(scrolledY / (float) mContentRect.height());
                    mEdgeEffectTopActive = true;
                }
                if (canScrollX && scrolledX > mMaxScrollBuffer.x) {
                    mEdgeEffectRight.onPull((scrolledX - mMaxScrollBuffer.x) / (float) mContentRect.width());
                    mEdgeEffectRightActive = true;
                }
                if (canScrollY && scrolledY > mMaxScrollBuffer.y) {
                    mEdgeEffectBottom.onPull((scrolledY - mMaxScrollBuffer.y) / (float) mContentRect.height());
                    mEdgeEffectBottomActive = true;
                }
            }

            ViewCompat.postInvalidateOnAnimation(ScaleImageView.this);
            return true;
        }

        private void disallowParentInterceptWhenOnEdge(float directionX, float directionY) {
            final ViewParent parent = getParent();
            if (parent != null && (mAllowParentHorizontalScroll || mAllowParentVerticalScroll)) {
                getImageRect(mRectF);
                if (mAllowParentHorizontalScroll) {
                    if (directionX > 0 && Math.abs(mRectF.right - mContentRect.right) > mMinEdge) {
                        parent.requestDisallowInterceptTouchEvent(true);
                    }
                    if (directionX < 0 && Math.abs(mRectF.left - mContentRect.left) > mMinEdge) {
                        parent.requestDisallowInterceptTouchEvent(true);
                    }
                }
                if (mAllowParentVerticalScroll) {
                    if (directionY > 0 && Math.abs(mRectF.bottom - mContentRect.bottom) > mMinEdge) {
                        parent.requestDisallowInterceptTouchEvent(true);
                    }
                    if (directionY < 0 && Math.abs(mRectF.top - mContentRect.top) > mMinEdge) {
                        parent.requestDisallowInterceptTouchEvent(true);
                    }
                }
            }
        }

        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            disallowParentInterceptWhenOnEdge(velocityX, velocityY);
            fling((int) -velocityX, (int) -velocityY);
            return true;
        }
    };

    mScaleGestureDetector = new ScaleGestureDetector(context, scaleGestureListener);
    mGestureDetector = new GestureDetectorCompat(context, gestureListener);

    mScroller = new OverScroller(context);
    mZoomer = new Zoomer(context);

    // Sets up edge effects
    mEdgeEffectLeft = new EdgeEffectCompat(context);
    mEdgeEffectTop = new EdgeEffectCompat(context);
    mEdgeEffectRight = new EdgeEffectCompat(context);
    mEdgeEffectBottom = new EdgeEffectCompat(context);

    setSrcDrawable(src);
}

From source file:com.guodong.sun.guodong.widget.ZoomImageView.java

@Override
public boolean onScale(ScaleGestureDetector detector) {

    // mMinScale~mMaxScale

    float scale = getScale();
    float scaleFactor = detector.getScaleFactor();

    if (getDrawable() == null)
        return true;

    // //from   www  . jav a 2  s . com
    if ((scale < mMaxScale && scaleFactor > 1.0f) || (scale > mMinScale && scaleFactor < 1.0f)) {

        if (scale * scaleFactor < mMinScale) {

            scaleFactor = mMinScale / scale;
        }

        if (scale * scaleFactor > mMaxScale) {

            scale = mMaxScale / scale;
        }
        // 
        mScaleMatrix.postScale(scaleFactor, scaleFactor, detector.getFocusX(), detector.getFocusY());

        checkBorderAndCenterWhenScale();

        setImageMatrix(mScaleMatrix);
    }

    return true;
}