Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package au.id.alexn;
- import android.content.Context;
- import android.util.AttributeSet;
- import android.util.Log;
- import android.view.MotionEvent;
- import android.view.ScaleGestureDetector;
- import android.view.View;
- import android.widget.FrameLayout;
- /**
- * Layout that provides pinch-zooming of content. This view should have exactly one child
- * view containing the content.
- */
- public class ZoomLayout extends FrameLayout implements ScaleGestureDetector.OnScaleGestureListener {
- private enum Mode {
- NONE,
- DRAG,
- ZOOM
- }
- private static final String TAG = "ZoomLayout";
- private static final float MIN_ZOOM = 1.0f;
- private static final float MAX_ZOOM = 4.0f;
- private Mode mode = Mode.NONE;
- private float scale = 1.0f;
- private float lastScaleFactor = 0f;
- // Where the finger first touches the screen
- private float startX = 0f;
- private float startY = 0f;
- // How much to translate the canvas
- private float dx = 0f;
- private float dy = 0f;
- private float prevDx = 0f;
- private float prevDy = 0f;
- public ZoomLayout(Context context) {
- super(context);
- init(context);
- }
- public ZoomLayout(Context context, AttributeSet attrs) {
- super(context, attrs);
- init(context);
- }
- public ZoomLayout(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- init(context);
- }
- private void init(Context context) {
- final ScaleGestureDetector scaleDetector = new ScaleGestureDetector(context, this);
- this.setOnTouchListener(new View.OnTouchListener() {
- @Override
- public boolean onTouch(View view, MotionEvent motionEvent) {
- switch (motionEvent.getAction() & MotionEvent.ACTION_MASK) {
- case MotionEvent.ACTION_DOWN:
- Log.i(TAG, "DOWN");
- if (scale > MIN_ZOOM) {
- mode = Mode.DRAG;
- startX = motionEvent.getX() - prevDx;
- startY = motionEvent.getY() - prevDy;
- }
- break;
- case MotionEvent.ACTION_MOVE:
- if (mode == Mode.DRAG) {
- dx = motionEvent.getX() - startX;
- dy = motionEvent.getY() - startY;
- }
- break;
- case MotionEvent.ACTION_POINTER_DOWN:
- mode = Mode.ZOOM;
- break;
- case MotionEvent.ACTION_POINTER_UP:
- mode = Mode.DRAG;
- break;
- case MotionEvent.ACTION_UP:
- Log.i(TAG, "UP");
- mode = Mode.NONE;
- prevDx = dx;
- prevDy = dy;
- break;
- }
- scaleDetector.onTouchEvent(motionEvent);
- if ((mode == Mode.DRAG && scale >= MIN_ZOOM) || mode == Mode.ZOOM) {
- getParent().requestDisallowInterceptTouchEvent(true);
- float maxDx = (child().getWidth() - (child().getWidth() / scale)) / 2 * scale;
- float maxDy = (child().getHeight() - (child().getHeight() / scale))/ 2 * scale;
- dx = Math.min(Math.max(dx, -maxDx), maxDx);
- dy = Math.min(Math.max(dy, -maxDy), maxDy);
- Log.i(TAG, "Width: " + child().getWidth() + ", scale " + scale + ", dx " + dx
- + ", max " + maxDx);
- applyScaleAndTranslation();
- }
- return true;
- }
- });
- }
- // ScaleGestureDetector
- @Override
- public boolean onScaleBegin(ScaleGestureDetector scaleDetector) {
- Log.i(TAG, "onScaleBegin");
- return true;
- }
- @Override
- public boolean onScale(ScaleGestureDetector scaleDetector) {
- float scaleFactor = scaleDetector.getScaleFactor();
- Log.i(TAG, "onScale" + scaleFactor);
- if (lastScaleFactor == 0 || (Math.signum(scaleFactor) == Math.signum(lastScaleFactor))) {
- scale *= scaleFactor;
- scale = Math.max(MIN_ZOOM, Math.min(scale, MAX_ZOOM));
- lastScaleFactor = scaleFactor;
- } else {
- lastScaleFactor = 0;
- }
- return true;
- }
- @Override
- public void onScaleEnd(ScaleGestureDetector scaleDetector) {
- Log.i(TAG, "onScaleEnd");
- }
- private void applyScaleAndTranslation() {
- child().setScaleX(scale);
- child().setScaleY(scale);
- child().setTranslationX(dx);
- child().setTranslationY(dy);
- }
- private View child() {
- return getChildAt(0);
- }
- }
Add Comment
Please, Sign In to add comment