Android Pinch Zoom Layout Example

Pinch zoom ( in or out ) is an often-used gesture in android applications. It is very user-friendly and smooth to display something bigger or smaller to watch. This example will show you how to implement pinch zoom on an image in the android application.

1. Make Android App Pinch Zoom Enabled Steps.

  1. Create a class like OnPinchListner which extends ScaleGestureDetector.SimpleOnScaleGestureListener. This class will be used to monitor user pinch-zoom gestures.
    public class OnPinchListener extends ScaleGestureDetector.SimpleOnScaleGestureListener
  2. Override the onScale(ScaleGestureDetector detector) method of OnPinchListner class, this method will be invoked when the listener detects pinch-zoom gesture.
  3. Create class android.view.ScaleGestureDetector‘s object scaleGestureDetector with an instance of class OnPinchListener as the constructor input parameter.
    ScaleGestureDetector scaleGestureDetector = new ScaleGestureDetector(getApplicationContext(), onPinchListener);
  4. When the activity on touch event occurred, invoke scaleGestureDetector‘s onTouchEvent method to make it detect scale change gesture.
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        scaleGestureDetector.onTouchEvent(event);
        return true;
    }

2. Android Pinch Zoom Example.

If you can not watch the above video, you can see it on the youtube URL https://youtu.be/iALniC31f5M

  1. There is an image view widget in this example.
  2. When you run the example in the emulator. Click the control key ( Windows ) or command key ( Mac OS) and the left mouse key anywhere on the screen at the same time, you can zoom in and out the image.

3. Android Pinch Zoom Image View Source Code.

  1. Below is the example project source files list.
    D:\WORK\DEV2QA.COM-EXAMPLE-CODE\ANDROIDEXAMPLEPROJECT\ANDRIODPINCHZOOM
    │  .gitignore
    │  build.gradle
    │  gradle.properties
    │  gradlew
    │  gradlew.bat
    │  settings.gradle
    │
    ├─.idea
    │      gradle.xml
    │      misc.xml
    │      modules.xml
    │      runConfigurations.xml
    │
    ├─app
    │  │  .gitignore
    │  │  build.gradle
    │  │  proguard-rules.pro
    │  │
    │  └─src
    │      ├─androidTest
    │      │  └─java
    │      │      └─com
    │      │          └─dev2qa
    │      │              └─andriodpinchzoom
    │      │                      ExampleInstrumentedTest.java
    │      │
    │      ├─main
    │      │  │  AndroidManifest.xml
    │      │  │
    │      │  ├─java
    │      │  │  └─com
    │      │  │      └─dev2qa
    │      │  │          └─andriodpinchzoom
    │      │  │                  MainActivity.java
    │      │  │                  OnPinchListener.java
    │      │  │
    │      │  └─res
    │      │      ├─drawable
    │      │      │      green_button.jpg
    │      │      │      ic_launcher_background.xml
    │      │      │
    │      │      ├─drawable-v24
    │      │      │      ic_launcher_foreground.xml
    │      │      │
    │      │      ├─layout
    │      │      │      activity_main.xml
  2. Create an android project with the Empty Activity template. And then modify or add the below files in this project.
  3. Create the OnPinchListener java file.
  4. Modify MainActivity java file.
  5. Add green_button.jpg under the app/res/drawable folder.
  6. Modify app / res / layout / activity_main.xml file.
  7. AndroidManifest.xml file is created by the wizard and does not need to change.

3.1 Main Activity Java File.

  1. MainActivity.java
    package com.dev2qa.andriodpinchzoom;
    
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.MotionEvent;
    import android.view.ScaleGestureDetector;
    import android.widget.ImageView;
    
    public class MainActivity extends AppCompatActivity {
    
    
        // Pinch zoom will occurred on this image widget.
        private ImageView imageView = null;
    
        // Used to detect pinch zoom gesture.
        private ScaleGestureDetector scaleGestureDetector = null;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            setTitle("dev2qa.com - Andriod Pinch Zoom Example");
    
            initControls();
        }
    
        private void initControls()
        {
            if(imageView == null)
            {
                // Get the image view in the layout xml.
                imageView = (ImageView)findViewById(R.id.pinch_image_view);
            }
    
            if(scaleGestureDetector == null)
            {
                // Create an instance of OnPinchListner custom class.
                OnPinchListener onPinchListener = new OnPinchListener(getApplicationContext(), imageView);
    
                // Create the new scale gesture detector object use above pinch zoom gesture listener.
                scaleGestureDetector = new ScaleGestureDetector(getApplicationContext(), onPinchListener);
            }
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            // Dispatch activity on touch event to the scale gesture detector.
            scaleGestureDetector.onTouchEvent(event);
            return true;
        }
    }

3.2 Pinch Zoom Listener Java File.

  1. OnPinchListener.java
    package com.dev2qa.andriodpinchzoom;
    
    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.Bitmap.*;
    import android.graphics.Canvas;
    import android.graphics.Matrix;
    import android.graphics.Paint;
    import android.graphics.drawable.BitmapDrawable;
    import android.util.Log;
    import android.view.ScaleGestureDetector;
    import android.widget.ImageView;
    import android.widget.Toast;
    
    
    /* This listener is used to listen pinch zoom gesture. ß*/
    public class OnPinchListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
    
        private final static String TAG_PINCH_LISTENER = "PINCH_LISTENER";
    
        // Pinch zoon occurred on this image view object.
        private ImageView srcImageView = null;
    
        // Related appication context.
        private Context context = null;
    
        // The default constructor pass context and imageview object.
        public OnPinchListener(Context context, ImageView srcImageView) {
            this.context = context;
            this.srcImageView = srcImageView;
        }
    
        // When pinch zoom gesture occurred.
        @Override
        public boolean onScale(ScaleGestureDetector detector) {
    
            if(detector!=null) {
    
                float scaleFactor = detector.getScaleFactor();
    
                if (srcImageView != null) {
    
                    // Scale the image with pinch zoom value.
                    scaleImage(scaleFactor, scaleFactor);
    
                } else {
                    if (context != null) {
                        Toast.makeText(context, "", Toast.LENGTH_SHORT).show();
                    } else {
                        Log.e(TAG_PINCH_LISTENER, "Both context and srcImageView is null.");
                    }
                }
            }else
            {
                Log.e(TAG_PINCH_LISTENER, "Pinch listener onScale detector parameter is null.");
            }
    
            return true;
        }
    
        /* This method is used to scale the image when user pinch zoom it. */
        private void scaleImage(float xScale, float yScale)
        {
            // Get source image bitmap object.
            BitmapDrawable srcBitmapDrawable = (BitmapDrawable) srcImageView.getDrawable();
            Bitmap srcBitmap = srcBitmapDrawable.getBitmap();
    
            // Get source image width and height.
            int srcImageWith = srcBitmap.getWidth();
            int srcImageHeight = srcBitmap.getHeight();
    
            // Get source image config object.
            Config srcImageConfig = srcBitmap.getConfig();
    
            // Create a new bitmap which has scaled width and height value from source bitmap.
            Bitmap scaleBitmap = Bitmap.createBitmap((int)(srcImageWith * xScale), (int)(srcImageHeight * yScale), srcImageConfig);
    
            // Create the scaled canvas.
            Canvas scaleCanvas = new Canvas(scaleBitmap);
    
            // Create the Matrix object which will scale the source bitmap to target.
            Matrix scaleMatrix = new Matrix();
    
            // Set x y scale value.
            scaleMatrix.setScale(xScale, yScale);
    
            // Create a new paint object.
            Paint paint = new Paint();
    
            // Draw the new scaled bitmap in the canvas.
            scaleCanvas.drawBitmap(srcBitmap, scaleMatrix, paint);
    
            // Display the new scaled bitmap to source image view object.
            srcImageView.setImageBitmap(scaleBitmap);
        }
    }

3.3 Main Activity Layout Xml File.

  1. activity_main.xml
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:gravity="center">
    
        <ImageView
            android:id="@+id/pinch_image_view"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/green_button"
            android:scaleType="centerInside"/>
    
    </LinearLayout>
0 0 votes
Article Rating
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x