Android PhotoView如何恢复至之前的缩放位置(坐标与缩放比例)
Hey there! Let's work through how to get your PhotoView back to its exact zoom position after redrawing the Bitmap to remove points. You're right that setScale() is the way to go—we just need to figure out the correct focalX and focalY values, and we can use PhotoView's built-in methods to get them easily.
Step 1: Save the Current Zoom State Before Redrawing
Before you delete the point and redraw the Bitmap, capture two key pieces of information to maintain alignment:
- The current zoom scale (you already have this, but we can confirm it with PhotoView's API)
- The focal point in the PhotoView's coordinate system that we want to lock in (so the image stays visually in place)
The simplest way to get the focal point is using PhotoView's getDisplayRect() method, which returns the exact rectangle of the image as it's currently displayed within the View. Here's how to capture that:
// Save current zoom state float savedScale = photoView.getScale(); RectF currentDisplayRect = new RectF(); photoView.getDisplayRect(currentDisplayRect); // Calculate the focal point (center of the currently visible image area) float focalX = currentDisplayRect.centerX(); float focalY = currentDisplayRect.centerY();
Step 2: Redraw Your Bitmap
Proceed with your existing delete-and-redraw logic to update the Bitmap:
// Create a new Bitmap and redraw (adjust to match your existing code) Bitmap updatedBitmap = Bitmap.createBitmap(originalBitmap.getWidth(), originalBitmap.getHeight(), originalBitmap.getConfig()); Canvas canvas = new Canvas(updatedBitmap); Matrix drawMatrix = new Matrix(); canvas.drawBitmap(originalBitmap, drawMatrix, yourPaint); // Replace the old Bitmap in PhotoView photoView.setImageBitmap(updatedBitmap);
Step 3: Restore the Zoom Position
Once the new Bitmap is set, use the saved scale and focal point to snap the PhotoView back to its previous state:
// Restore zoom instantly (false disables animation) photoView.setScale(savedScale, focalX, focalY, false);
Why This Works
The setScale(scale, focalX, focalY, false) method tells PhotoView to:
- Scale the image to the specified
scalevalue - Keep the point at
(focalX, focalY)(relative to the PhotoView's top-left corner) fixed in place. Using the center of the previously visible image area ensures the image stays visually aligned exactly where it was before the redraw.
Alternative: Calculate from the Support Matrix
If you want to derive these values directly from the matrix (as you suspected), you can parse the support matrix's values manually:
Matrix currentMatrix = new Matrix(); photoView.getSuppMatrix(currentMatrix); float[] matrixValues = new float[9]; currentMatrix.getValues(matrixValues); // Extract scale (PhotoView uses uniform scaling, so scaleX = scaleY) float savedScale = matrixValues[0]; // Extract translation (dx, dy) of the image relative to the View float dx = matrixValues[2]; float dy = matrixValues[5]; // Calculate the visible image's center (matches getDisplayRect().centerX/Y()) int bitmapWidth = originalBitmap.getWidth(); int bitmapHeight = originalBitmap.getHeight(); float focalX = dx + (bitmapWidth * savedScale) / 2f; float focalY = dy + (bitmapHeight * savedScale) / 2f;
This gives you the exact same focal point as using getDisplayRect()—it's just a more manual approach.
Important Notes
- Ensure you call
getDisplayRect()orgetSuppMatrix()after the PhotoView has been laid out (not inonCreate()before the View is drawn). If you need to capture state early, useView.post()to run the code after layout completes. - Using
falseinsetScale()ensures the restore happens instantly, which is ideal for this use case (no unwanted animation when updating the image).
内容的提问来源于stack exchange,提问作者Pepa Zapletal

