Skip to content

Instantly share code, notes, and snippets.

@nbarraille
Last active December 10, 2020 07:35
  • Star 16 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save nbarraille/eb5d0da20bc813969b08 to your computer and use it in GitHub Desktop.
/*
* The MIT License (MIT)
*
* Copyright (c) 2015 - Nathan Barraille
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import com.facebook.drawee.view.SimpleDraweeView;
/**
* A SimpleDraweeView that supports Pinch to zoom.
*/
public class PinchToZoomDraweeView extends SimpleDraweeView {
private final ScaleGestureDetector mScaleDetector;
private final ScaleGestureDetector.OnScaleGestureListener mScaleListener;
private float mCurrentScale;
private final Matrix mCurrentMatrix;
private float mMidX;
private float mMidY;
@Nullable private OnZoomChangeListener mListener;
public PinchToZoomDraweeView(Context context) {
this(context, null);
}
public PinchToZoomDraweeView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public PinchToZoomDraweeView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mScaleListener = new ScaleGestureDetector.SimpleOnScaleGestureListener() {
@Override
public boolean onScale(ScaleGestureDetector detector) {
float scaleFactor = detector.getScaleFactor();
float newScale = mCurrentScale * scaleFactor;
// Prevent from zooming out more than original
if (newScale > 1.0f) {
// We initialize this lazily so that we don't have to register (and force the user
// to unregister) a global layout listener on the view.
if (mMidX == 0.0f) {
mMidX = getWidth() / 2.0f;
}
if (mMidY == 0.0f) {
mMidY = getHeight() / 2.0f;
}
mCurrentScale = newScale;
mCurrentMatrix.postScale(scaleFactor, scaleFactor, mMidX, mMidY);
invalidate();
} else {
scaleFactor = 1.0f / mCurrentScale;
reset();
}
if (mListener != null && scaleFactor != 1.0f) {
mListener.onZoomChange(mCurrentScale);
}
return true;
}
};
mScaleDetector = new ScaleGestureDetector(getContext(), mScaleListener);
mCurrentMatrix = new Matrix();
}
public void setOnZoomChangeListener(OnZoomChangeListener listener) {
mListener = listener;
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
setOnZoomChangeListener(null);
}
@Override
protected void onDraw(@NonNull Canvas canvas) {
int saveCount = canvas.save();
canvas.concat(mCurrentMatrix);
super.onDraw(canvas);
canvas.restoreToCount(saveCount);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
return mScaleDetector.onTouchEvent(event) || super.onTouchEvent(event);
}
/**
* Resets the zoom on that view
*/
public void resetZoom() {
reset();
}
/**
* Resets the zoom of the attached image.
* This has no effect if the image has been destroyed
*/
public void reset() {
mCurrentMatrix.reset();
mCurrentScale = 1.0f;
invalidate();
}
/**
* A listener interface for when the zoom scale changes
*/
public interface OnZoomChangeListener {
/**
* Callback method getting triggered when the zoom scale changes.
* This is not called when the zoom is programmatically reset
* @param scale the new scale
*/
public void onZoomChange(float scale);
}
}
@hendrawd
Copy link

hendrawd commented Oct 2, 2015

It will be useful if you can add a functionality to make the image move by drag. For now, it's only zooming with anchor center. Thanks anyway for the gist :)

Edit : Ok, so it is an example of how to pinch zoom drawee view. I got the solution for pinch zoom and drag image https://github.com/facebook/fresco/blob/master/samples/zoomable/src/main/java/com/facebook/samples/zoomable/ZoomableDraweeView.java if anyone want to use.

@joginder89
Copy link

@nbarraille
Thank you for code.

@hendrawd
Please not if are going to use in commercial project.
This file provided by Facebook is for non-commercial testing and evaluation purposes only. Facebook reserves all rights not expressly granted.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment