Durchführen von Prise Zoom und Ziehen mit Android's Build in Gesten Zuhörer und Skala Zuhörer

Ich versuche, Pinch-Zoom zu implementieren und mit Android-Gesten-Listener und Skala-Hörer zu ziehen. Das Problem ist, dass, wenn ich Pinch Zoom, das Bild (die ich versuche zu zoomen) springt auf einen bestimmten Ort. Auch die Zoomposition ist nicht zentriert. Der folgende Code zeigt, was ich zu erreichen versuche. Jede Idee, warum das Bild springt (und wie man es korrigiert)?

public class CustomView extends View { Bitmap image; int screenHeight; int screenWidth; Paint paint; GestureDetector gestures; ScaleGestureDetector scaleGesture; float scale = 1.0f; float horizontalOffset, verticalOffset; int NORMAL = 0; int ZOOM = 1; int DRAG = 2; boolean isScaling = false; float touchX, touchY; int mode = NORMAL; public CustomView(Context context) { super(context); //initializing variables image = BitmapFactory.decodeResource(getResources(), R.drawable.image_name); //This is a full screen view screenWidth = getResources().getDisplayMetrics().widthPixels; screenHeight = getResources().getDisplayMetrics().heightPixels; paint = new Paint(); paint.setAntiAlias(true); paint.setFilterBitmap(true); paint.setDither(true); paint.setColor(Color.WHITE); scaleGesture = new ScaleGestureDetector(getContext(), new ScaleListener()); gestures = new GestureDetector(getContext(), new GestureListener()); mode = NORMAL; initialize(); } //Best fit image display on canvas private void initialize() { float imgPartRatio = image.getWidth() / (float) image.getHeight(); float screenRatio = (float) screenWidth / (float) screenHeight; if (screenRatio > imgPartRatio) { scale = ((float) screenHeight) / (float) (image.getHeight()); // fit height horizontalOffset = ((float) screenWidth - scale * (float) (image.getWidth())) / 2.0f; verticalOffset = 0; } else { scale = ((float) screenWidth) / (float) (image.getWidth()); // fit width horizontalOffset = 0; verticalOffset = ((float) screenHeight - scale * (float) (image.getHeight())) / 2.0f; } invalidate(); } @Override protected void onDraw(Canvas canvas) { canvas.save(); canvas.drawColor(0, Mode.CLEAR); canvas.drawColor(Color.WHITE); if(mode == DRAG || mode == NORMAL) { //This works perfectly as expected canvas.translate(horizontalOffset, verticalOffset); canvas.scale(scale, scale); canvas.drawBitmap(image, getMatrix(), paint); } else if (mode == ZOOM) { //PROBLEM AREA - when applying pinch zoom, //the image jumps to a position abruptly canvas.scale(scale, scale, touchX, touchY); canvas.drawBitmap(image, getMatrix(), paint); } canvas.restore(); } public class ScaleListener implements OnScaleGestureListener { @Override public boolean onScale(ScaleGestureDetector detector) { float scaleFactorNew = detector.getScaleFactor(); if (detector.isInProgress()) { touchX = detector.getFocusX(); touchY = detector.getFocusY(); scale *= scaleFactorNew; invalidate(0, 0, screenWidth, screenHeight); } return true; } @Override public boolean onScaleBegin(ScaleGestureDetector detector) { isScaling = true; mode=ZOOM; return true; } @Override public void onScaleEnd(ScaleGestureDetector detector) { mode = NORMAL; isScaling = false; } } public class GestureListener implements GestureDetector.OnGestureListener, GestureDetector.OnDoubleTapListener { @Override public boolean onDown(MotionEvent e) { isScaling = false; return true; } @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { if (!isScaling) { mode = DRAG; isScaling = false; horizontalOffset -= distanceX; verticalOffset -= distanceY; invalidate(0, 0, screenWidth, screenHeight); } else { mode = ZOOM; isScaling = true; } return true; } } @Override public boolean onTouchEvent(MotionEvent event) { scaleGesture.onTouchEvent(event); gestures.onTouchEvent(event); return true; } } 

Danke im Voraus.

  • Leuchtkasten nicht spielen nett mit mobilen Gerät
  • Wie zoomen Sie das Objekt aus der Mitte der Prise
  • Pinch Zoom auf ein Bild in Xamarin
  • Ändern Sie die Größe von ImageView beim Zoomen
  • Ziehe mehrere Ansichten in einem verschiebbaren Bereich in Android (wie Snapchat)
  • Mpandroidchart - Wie kann ich die wiederholten Werte in Y-Achse vermeiden?
  • Android-Swipe-Karte mit Prise zum Zoomen von Bildansicht mit SwipeFlingAdapterView-Bibliothek
  • Android ImageView Zoom mit Textüberlagerung
  • One Solution collect form web for “Durchführen von Prise Zoom und Ziehen mit Android's Build in Gesten Zuhörer und Skala Zuhörer”

    Ich habe dieses Verhalten implementiert, und ich habe eine Matrix verwendet, um alle Zooming und Scrollen (und Rotation, in meinem Fall) zu behandeln. Es macht für ordentlichen Code und funktioniert wie Uhrwerk.

    Eine Matrix als Klassenmitglied speichern:

     Matrix drawMatrix; 

    Bearbeiten: Speichern Sie den alten Fokuspunkt, um die Fokusverschiebung während der Skalierung zu erhalten.

     float lastFocusX; float lastFocusY; 

    Bearbeiten : Legen Sie lastFocus-Variablen in onScaleBegin fest

     @Override public boolean onScaleBegin(ScaleGestureDetector detector) { lastFocusX = detector.getFocusX(); lastFocusY = detector.getFocusY(); return true; } 

    Ersetzen Sie Ihre onScale:

     @Override public boolean onScale(ScaleGestureDetector detector) { Matrix transformationMatrix = new Matrix(); float focusX = detector.getFocusX(); float focusY = detector.getFocusY(); //Zoom focus is where the fingers are centered, transformationMatrix.postTranslate(-focusX, -focusY); transformationMatrix.postScale(detector.getScaleFactor(), detector.getScaleFactor()); /* Adding focus shift to allow for scrolling with two pointers down. Remove it to skip this functionality. This could be done in fewer lines, but for clarity I do it this way here */ //Edited after comment by chochim float focusShiftX = focusX - lastFocusX; float focusShiftY = focusY - lastFocusY; transformationMatrix.postTranslate(focusX + focusShiftX, focusY + focusShiftY); drawMatrix.postConcat(transformationMatrix); lastFocusX = focusX; lastFocusY = focusY; invalidate(); return true; } 

    Ähnlich in onScroll:

     @Override public boolean onScroll(MotionEvent downEvent, MotionEvent currentEvent, float distanceX, float distanceY) { drawMatrix.postTranslate(-distanceX, -distanceY); invalidate(); return true; } 

    In onDraw; Zeichne mit deinem DrawMatrix:

     canvas.drawBitmap(image, drawMatrix, paint); 

    Glückliche Kodierung!

    Das Android ist ein Google Android Fan-Website, Alles ├╝ber Android Phones, Android Wear, Android Dev und Android Spiele Apps und so weiter.