korunos
korunos

Reputation: 798

Set Max and Min zoom on TouchEvent in Android

I copied this kind of code to make a ImageView scrollable.

example.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            ImageView view = (ImageView) v;
            view.setScaleType(ImageView.ScaleType.MATRIX);
            float scale;

            dumpEvent(event);
            //Handle touch events here...

            switch (event.getAction() & MotionEvent.ACTION_MASK) {
                case MotionEvent.ACTION_DOWN: //first finger down only
                    savedMatrix.set(matrix);
                    start.set(event.getX(), event.getY());
                    Log.d(TAG, "mode=DRAG");
                    mode = DRAG;
                    break;
                case MotionEvent.ACTION_UP://first finger lifted

                case MotionEvent.ACTION_POINTER_UP: //second finger lifted
                    mode = NONE;
                    Log.d(TAG, "mode=NONE");
                    break;
                case MotionEvent.ACTION_POINTER_DOWN: //first and second finger down
                    oldDist = spacing(event);
                    Log.d(TAG, "oldDist=" + oldDist);
                    if (oldDist > 10f) {
                        savedMatrix.set(matrix);
                        midPoint(mid, event);
                        mode = ZOOM;
                        Log.d(TAG, "mode=ZOOM");
                    }
                    break;
                case MotionEvent.ACTION_MOVE:
                    if (mode == DRAG) {
                        matrix.set(savedMatrix);
                        matrix.postTranslate(event.getX() - start.x, event.getY() - start.y); //create the transformation in the matrix of points
                    } else if (mode == ZOOM) {
                        //pinch zooming
                        float newDist = spacing(event);
                        Log.d(TAG, "newDist=" + newDist);
                        if (newDist > 10f) {
                            matrix.set(savedMatrix);
                            scale = newDist / oldDist; //setting the scaling of the matrix...
                            //if scale > 1 means zoom in
                            // if scale < 1 means zoom out
                            matrix.postScale(scale, scale, mid.x, mid.y);
                        }
                    }
                    break;
            }
            view.setImageMatrix(matrix); //display the transformation on screen

            return true; //indicate event was handled
        }

private float spacing(MotionEvent event) {
            float x = event.getX(0) - event.getX(1);
            float y = event.getY(0) - event.getY(1);
            return FloatMath.sqrt(x * x + y * y);
        }

        /*
         * --------------------------------------------------------------------------
         * Method: midPoint Parameters: PointF object, MotionEvent Returns: void
         * Description: calculates the midpoint between the two fingers
         * ------------------------------------------------------------
         */

        private void midPoint(PointF point, MotionEvent event) {
            float x = event.getX(0) + event.getX(1);
            float y = event.getY(0) + event.getY(1);
            point.set(x / 2, y / 2);
        }

Where do I have to put a variable to set a max and min zoom.

At the Moment I can zoom in or out endless.

Kind Regards!

Upvotes: 2

Views: 2356

Answers (3)

Skizo-ozᴉʞS ツ
Skizo-ozᴉʞS ツ

Reputation: 20646

You have to create a MIN_ZOOM, MAX_ZOOM, and then scale it as follows :

private static final float MIN_ZOOM = 1.0f; 
private static final float MAX_ZOOM = WHAT_YOU_WANT; 
float scale = Math.max(MIN_ZOOM, Math.min(scale, MAX_ZOOM));

For more information check this answer

Upvotes: 3

Ansal Ali
Ansal Ali

Reputation: 1613

 case MotionEvent.ACTION_MOVE:
                    if (mode == DRAG) { 
                        matrix.set(savedMatrix); 
                        matrix.postTranslate(event.getX() - start.x, event.getY() - start.y); //create the transformation in the matrix of points
                    } else if (mode == ZOOM) { 
                        //pinch zooming 
                        float newDist = spacing(event);
                        Log.d(TAG, "newDist=" + newDist);
                        if (newDist > 10f) {
                            matrix.set(savedMatrix); 
                            scale = newDist / oldDist; //setting the scaling of the matrix...
                            //if scale > 1 means zoom in 
                            // if scale < 1 means zoom out

/* Here you can add some thing like this*/

                      if(scale >= 1 && scale < maxZoom || scale <1 && scale >= minZoom){

                                matrix.postScale(scale, scale, mid.x, mid.y);
                              }
                        } 
                    } 

maxZoom = 5 or whatever value you want

minZoom = 0.25 or whatever value you want

Upvotes: 0

Oleksandr
Oleksandr

Reputation: 6356

You should have variable for total scale, because your scale is just diff between current scale and previous scale. And normalize your local scale if you total out of bounds.

    // normalize scale
    if (scale * scaleAll > MAX_ZOOM) {
        scale = MAX_ZOOM / scaleAll;
    }
    if (scale * scaleAll < MIN_ZOOM) {
        scale = MIN_ZOOM / scaleAll;
    }

The all code would be:

private static final float MIN_ZOOM = 0.1f;
private static final float MAX_ZOOM = 4f;
private float scaleAll = 1;

boolean someMethod() {
    // Some code
    example.setOnTouchListener(new View.OnTouchListener()        {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            ImageView view = (ImageView) v;
            view.setScaleType(ImageView.ScaleType.MATRIX);
            float scale;

            dumpEvent(event);
            //Handle touch events here...

            switch (event.getAction() & MotionEvent.ACTION_MASK) {
                case MotionEvent.ACTION_DOWN: //first finger down only
                    savedMatrix.set(matrix);
                    start.set(event.getX(), event.getY());
                    Log.d(TAG, "mode=DRAG");
                    mode = DRAG;
                    break;
                case MotionEvent.ACTION_UP://first finger lifted

                case MotionEvent.ACTION_POINTER_UP: //second finger lifted
                    mode = NONE;
                    Log.d(TAG, "mode=NONE");
                    break;
                case MotionEvent.ACTION_POINTER_DOWN: //first and second finger down
                    oldDist = spacing(event);
                    Log.d(TAG, "oldDist=" + oldDist);
                    if (oldDist > 10f) {
                        savedMatrix.set(matrix);
                        midPoint(mid, event);
                        mode = ZOOM;
                        Log.d(TAG, "mode=ZOOM");
                    }
                    break;
                case MotionEvent.ACTION_MOVE:
                    if (mode == DRAG) {
                        matrix.set(savedMatrix);
                        matrix.postTranslate(event.getX() - start.x, event.getY() - start.y); //create the transformation in the matrix of points
                    } else if (mode == ZOOM) {
                        //pinch zooming
                        float newDist = spacing(event);
                        Log.d(TAG, "newDist=" + newDist);
                        if (newDist > 10f) {
                            scale = newDist / oldDist; //setting the scaling of the matrix...

                            // normalize scale
                            if (scale * scaleAll > MAX_ZOOM) {
                                scale = MAX_ZOOM / scaleAll;
                            }
                            if (scale * scaleAll < MIN_ZOOM) {
                                scale = MIN_ZOOM / scaleAll;
                            }
                            scaleAll*=scale;
                            matrix.set(savedMatrix);
                            //if scale > 1 means zoom in
                            // if scale < 1 means zoom out
                            matrix.postScale(scale, scale, mid.x, mid.y);
                        }
                    }
                    break;
            }
            view.setImageMatrix(matrix); //display the transformation on screen

            return true; //indicate event was handled
        }
    }
}

Upvotes: 0

Related Questions