Android ImageViewer Class Supporting Pinch-Zoom and Scrolling
Introduction
This article delves into the creation of a custom Android ImageViewer class that implements pinch-zoom and scrolling functionality. The class leverages the power of Android’s touch events to provide a user-friendly and interactive image viewing experience.
Implementation
1. **ImageViewer Class:**
“`java
import android.content.Context;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.widget.ImageView;
public class ImageViewer extends ImageView {
private Matrix matrix = new Matrix();
private ScaleGestureDetector scaleGestureDetector;
private float scale = 1f;
private float minScale = 1f;
private float maxScale = 4f;
private PointF lastTouchPoint = new PointF();
private boolean isZoomed = false;
public ImageViewer(Context context) {
super(context);
init();
}
public ImageViewer(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public ImageViewer(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
scaleGestureDetector = new ScaleGestureDetector(getContext(), new ScaleListener());
setImageMatrix(matrix);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
scaleGestureDetector.onTouchEvent(event);
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
lastTouchPoint.set(event.getX(), event.getY());
break;
case MotionEvent.ACTION_MOVE:
if (event.getPointerCount() == 1 && isZoomed) {
float dx = event.getX() – lastTouchPoint.x;
float dy = event.getY() – lastTouchPoint.y;
matrix.postTranslate(dx, dy);
setImageMatrix(matrix);
lastTouchPoint.set(event.getX(), event.getY());
}
break;
}
return true;
}
private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
@Override
public boolean onScale(ScaleGestureDetector detector) {
scale *= detector.getScaleFactor();
scale = Math.max(minScale, Math.min(scale, maxScale));
matrix.setScale(scale, scale, detector.getFocusX(), detector.getFocusY());
setImageMatrix(matrix);
isZoomed = scale > minScale;
return true;
}
}
}
“`
2. **Layout File (activity_main.xml):**
“`xml
“`
3. **Activity File (MainActivity.java):**
“`java
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
“`
Usage
* In your layout file, use the custom `ImageViewer` class instead of the standard `ImageView`.
* Set the `android:src` attribute to your image resource.
* The `android:scaleType` attribute is set to `matrix` to enable custom matrix transformations.
Explanation
1. **Pinch-Zoom:**
* `ScaleGestureDetector` is used to detect pinch gestures.
* `onScale()` in the `ScaleListener` updates the scale factor and applies it to the `matrix`.
* The `minScale` and `maxScale` variables limit the zoom range.
2. **Scrolling:**
* `ACTION_DOWN` records the initial touch point.
* `ACTION_MOVE` translates the `matrix` based on the touch movement if the image is zoomed.
* The `isZoomed` flag prevents scrolling when the image is not zoomed.
Conclusion
This custom ImageViewer class provides a flexible and interactive image viewing experience with pinch-zoom and scrolling functionality. It’s a valuable addition to Android apps requiring image display with user interaction. Remember to adapt the code and layout file according to your specific image and layout requirements.