How to enable pinch zooming in the image switcher?

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-10 13:07:44

问题


The application's interface consists of the following items.

  1. An image switcher that fills the entire screen.
  2. A next button.
  3. A previous button.

How can I use the pinch zooming in the image Switcher?


回答1:


Implementing the Pinch Zoom Gesture

The pinch zoom gesture is similar to the drag gesture, except it starts when the second finger is pressed to the screen (ACTION_POINTER_DOWN).

case MotionEvent.ACTION_POINTER_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) {
// ...
}
else if (mode == ZOOM) {
float newDist = spacing(event);
Log.d(TAG, "newDist=" + newDist);
if (newDist > 10f) {
matrix.set(savedMatrix);
float scale = newDist / oldDist;
matrix.postScale(scale, scale, mid.x, mid.y);
}
}
break;

When we get the down event for the second finger, we calculate and remember the distance between the two fingers. In my testing, Android would sometimes tell me (incorrectly) that there were two fingers pressed down in almost exactly the same position. So I added an check to ignore the event if the distance is smaller than some arbitrary number of pixels. If it’s bigger than that, we remember the current transformation matrix, calculate the midpoint of the two fingers, and start the zoom.

When a move event arrives while we’re in zoom mode, we calculate the distance between the fingers again. If it’s too small, the event is ignored, otherwise we restore the transformation matrix and scale the image around the midpoint.

The scale is simply the ratio of the new distance divided by the old distance. If the new distance is bigger (that is, the fingers have gotten further apart), then the scale will be greater than 1, making the image bigger. If it’s smaller (fingers closer together), then the scale will be less than one, making the image smaller. And of course if everything is the same, the scale is equal to 1 and the image is not changed.

Now let’s define the spacing() and midPoint() methods.

Distance Between Two Points

To find out how far apart two fingers are, we first construct a vector (x, y) which is the difference between the two points.

Then we use the formula for Euclidean distance to calculate the spacing:

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);
}

The order of the points doesn’t matter because any negative signs will be lost when we square them. Note that all math is done using Java’s float type. While some Android devices may not have floating point hardware, we’re not doing this often enough to worry about its performance.

Midpoint of Two Points

Calculating a point in the middle of two points is even easier:

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);
}

All we do is take the average of their X and Y coordinates. To avoid garbage collections that can cause noticeable pauses in the application, we reuse an existing object to store the result rather than allocating and returning a new one each time. Try running the program now on your phone. Drag the image with one finger, and zoom it by pinching two fingers in or out. For best results, don’t let your fingers get closer than an inch or so apart. Otherwise you’ll start to run into some of those bugs in the API I mentioned earlier.

This is an excerpt from Hello, Android 3rd edition, published by the Pragmatic Bookshelf. For more information or to purchase a paperback or PDF copy, please visit http://www.pragprog.com/titles/eband3



来源:https://stackoverflow.com/questions/13552874/how-to-enable-pinch-zooming-in-the-image-switcher

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!