Ограничение масштаба при увеличении зума андроида

Как установить уровни масштабирования Max и Min для Pinch-Zoom?


Вот мой код: //

public class TouchImageView extends ImageView { private static final String TAG = "Touch"; // These matrices will be used to move and zoom image Matrix matrix = new Matrix(); Matrix savedMatrix = new Matrix(); static PinchZoomExample sPinchZoomExample = null; // We can be in one of these 3 states static final int NONE = 0; static final int DRAG = 1; static final int ZOOM = 2; int mode = NONE; static Bitmap sCurrentImage; // Remember some things for zooming PointF start = new PointF(); PointF mid = new PointF(); float oldDist = 1f; Context context; public TouchImageView(Context context) { super(context); super.setClickable(true); this.context = context; matrix.setTranslate(1f, 1f); setImageMatrix(matrix); setScaleType(ScaleType.MATRIX); setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent rawEvent) { WrapMotionEvent event = WrapMotionEvent.wrap(rawEvent); // Dump touch event to log /* if (Viewer.isDebug == true){ dumpEvent(event); }*/ // Handle touch events here... switch (event.getAction() & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: savedMatrix.set(matrix); start.set(event.getX(), event.getY()); Log.d(TAG, "mode=DRAG"); mode = DRAG; break; 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_UP: int xDiff = (int) Math.abs(event.getX() - start.x); int yDiff = (int) Math.abs(event.getY() - start.y); if (xDiff < 8 && yDiff < 8){ performClick(); sPinchZoomExample.displayGallery(); } case MotionEvent.ACTION_POINTER_UP: mode = NONE; Log.d(TAG, "mode=NONE"); break; case MotionEvent.ACTION_MOVE: if (mode == DRAG) { // ... matrix.set(savedMatrix); matrix.postTranslate(event.getX() - start.x, event.getY() - start.y); } 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); //Canvas canvas = new Canvas(); // Bitmap bm = Bitmap.createBitmap(sCurrentImage,0, 0, sCurrentImage.getWidth() // , sCurrentImage.getHeight(), matrix, true); Log.d("SCALE", "scale=" + scale + " " + getWidth() + " " + getHeight()); //bm.recycle(); } } break; } setImageMatrix(matrix); return true; // indicate event was handled } }); } public void setImage(Bitmap bm, int displayWidth, int displayHeight , PinchZoomExample pze) { super.setImageBitmap(bm); sCurrentImage = bm; sPinchZoomExample = pze; //Fit to screen. float scale; if ((displayHeight / bm.getHeight()) >= (displayWidth / bm.getWidth())){ scale = (float)displayWidth / (float)bm.getWidth(); } else { scale = (float)displayHeight / (float)bm.getHeight(); } savedMatrix.set(matrix); matrix.set(savedMatrix); matrix.postScale(scale, scale, mid.x, mid.y); setImageMatrix(matrix); // Center the image float redundantYSpace = (float)displayHeight - (scale * (float)bm.getHeight()) ; float redundantXSpace = (float)displayWidth - (scale * (float)bm.getWidth()); redundantYSpace /= (float)2; redundantXSpace /= (float)2; savedMatrix.set(matrix); matrix.set(savedMatrix); matrix.postTranslate(redundantXSpace, redundantYSpace); //matrix.postTranslate(50, 50); setImageMatrix(matrix); } /** Determine the space between the first two fingers */ private float spacing(WrapMotionEvent event) { // ... float x = event.getX(0) - event.getX(1); float y = event.getY(0) - event.getY(1); return FloatMath.sqrt(x * x + y * y); } /** Calculate the mid point of the first two fingers */ private void midPoint(PointF point, WrapMotionEvent event) { // ... float x = event.getX(0) + event.getX(1); float y = event.getY(0) + event.getY(1); point.set(x / 2, y / 2); } } 

Solutions Collecting From Web of "Ограничение масштаба при увеличении зума андроида"

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

Проверьте мой ответ здесь. Он работал с очень небольшим количеством дополнительных усилий по кодированию.

https://stackoverflow.com/a/18395969/2709830

 if(mapZoom > MAX_ZOOM && (newDist > oldDist) ) { break; } else if(mapZoom < MIN_Zoom && (newDist < oldDist) ){ break; } matrix.postScale(zoomScale, zoomScale, mid.x, mid.y); savedMatrixZoom.set(matrix); 

Он отлично работает, но все же я теряю эту гладкость и слишком чувствителен.

Создайте временную матрицу (temp), сохраните в ней текущую матрицу и масштабируйте матрицу temp. Затем проверьте значение MSCALE_X временной матрицы.

Если масштабирование вашей временной матрицы находится в пределах вашего предела, запишите свою матрицу и сохраните ее в другой матрице (savedMatrixZoom). Если это превышает ваш лимит, просто загрузите текущую матрицу из SavedMatrixZoom.

  else if (mode == ZOOM) { float newDist = spacing(event); Log.d(TAG, "newDist=" + newDist); if (newDist > 10f) { matrix.set(savedMatrix); zoomScale = newDist / oldDist; Matrix temp = new Matrix(); temp.set(matrix); temp.postScale(zoomScale, zoomScale, mid.x, mid.y); mapZoom = getValue(temp, Matrix.MSCALE_X); if (mapZoom < MAX_ZOOM && mapZoom > MIN_ZOOM) { matrix.postScale(zoomScale, zoomScale, mid.x, mid.y); savedMatrixZoom.set(matrix); } else { matrix.set(savedMatrixZoom); } } } 

Надеюсь, поможет