- Common ways to obtain SubsamplingScaleImageView
private void myMethod () {}
/** * Externally change the scale and translation of the source image. This may be used with getCenter() and getScale() * to restore the scale and zoom after a screen rotate. * @param scale New scale to set. * @param sCenter New source image coordinate to center on the screen, subject to boundaries. */ public final void setScaleAndCenter(float scale, @Nullable PointF sCenter) { this.anim = null; this.pendingScale = scale; this.sPendingCenter = sCenter; this.sRequestedCenter = sCenter; invalidate(); }
/** * Set a solid color to render behind tiles, useful for displaying transparent PNGs. * @param tileBgColor Background color for tiles. */ public final void setTileBackgroundColor(int tileBgColor) { if (Color.alpha(tileBgColor) == 0) { tileBgPaint = null; } else { tileBgPaint = new Paint(); tileBgPaint.setStyle(Style.FILL); tileBgPaint.setColor(tileBgColor); } invalidate(); }
/** * Set the pan limiting style. See static fields. Normally {@link #PAN_LIMIT_INSIDE} is best, for image galleries. * @param panLimit a pan limit constant. See static fields. */ public final void setPanLimit(int panLimit) { if (!VALID_PAN_LIMITS.contains(panLimit)) { throw new IllegalArgumentException("Invalid pan limit: " + panLimit); } this.panLimit = panLimit; if (isReady()) { fitToBounds(true); invalidate(); } }
/** * Sets the image orientation. It's best to call this before setting the image file or asset, because it may waste * loading of tiles. However, this can be freely called at any time. * @param orientation orientation to be set. See ORIENTATION_ static fields for valid values. */ public final void setOrientation(int orientation) { if (!VALID_ORIENTATIONS.contains(orientation)) { throw new IllegalArgumentException("Invalid orientation: " + orientation); } this.orientation = orientation; reset(false); invalidate(); requestLayout(); }
/** * Set the minimum scale type. See static fields. Normally {@link #SCALE_TYPE_CENTER_INSIDE} is best, for image galleries. * @param scaleType a scale type constant. See static fields. */ public final void setMinimumScaleType(int scaleType) { if (!VALID_SCALE_TYPES.contains(scaleType)) { throw new IllegalArgumentException("Invalid scale type: " + scaleType); } this.minimumScaleType = scaleType; if (isReady()) { fitToBounds(true); invalidate(); } }
/** * Called by worker task when preview image is loaded. */ private synchronized void onPreviewLoaded(Bitmap previewBitmap) { debug("onPreviewLoaded"); if (bitmap != null || imageLoadedSent) { previewBitmap.recycle(); return; } if (pRegion != null) { bitmap = Bitmap.createBitmap(previewBitmap, pRegion.left, pRegion.top, pRegion.width(), pRegion.height()); } else { bitmap = previewBitmap; } bitmapIsPreview = true; if (checkReady()) { invalidate(); requestLayout(); } }
/** * By default, image tiles are at least as high resolution as the screen. For a retina screen this may not be * necessary, and may increase the likelihood of an OutOfMemoryError. This method sets a DPI at which higher * resolution tiles should be loaded. Using a lower number will on average use less memory but result in a lower * quality image. 160-240dpi will usually be enough. This should be called before setting the image source, * because it affects which tiles get loaded. When using an untiled source image this method has no effect. * @param minimumTileDpi Tile loading threshold. */ public void setMinimumTileDpi(int minimumTileDpi) { DisplayMetrics metrics = getResources().getDisplayMetrics(); float averageDpi = (metrics.xdpi + metrics.ydpi)/2; this.minimumTileDpi = (int)Math.min(averageDpi, minimumTileDpi); if (isReady()) { reset(false); invalidate(); } }
/** * Fully zoom out and return the image to the middle of the screen. This might be useful if you have a view pager * and want images to be reset when the user has moved to another page. */ public final void resetScaleAndCenter() { this.anim = null; this.pendingScale = limitedScale(0); if (isReady()) { this.sPendingCenter = new PointF(sWidth()/2, sHeight()/2); } else { this.sPendingCenter = new PointF(0, 0); } invalidate(); }
/** * Set scale, center and orientation from saved state. */ private void restoreState(ImageViewState state) { if (state != null && VALID_ORIENTATIONS.contains(state.getOrientation())) { this.orientation = state.getOrientation(); this.pendingScale = state.getScale(); this.sPendingCenter = state.getCenter(); invalidate(); } }
/** * Called by worker task when full size image bitmap is ready (tiling is disabled). */ private synchronized void onImageLoaded(Bitmap bitmap, int sOrientation, boolean bitmapIsCached) { debug("onImageLoaded"); // If actual dimensions don't match the declared size, reset everything. if (this.sWidth > 0 && this.sHeight > 0 && (this.sWidth != bitmap.getWidth() || this.sHeight != bitmap.getHeight())) { reset(false); } if (this.bitmap != null && !this.bitmapIsCached) { this.bitmap.recycle(); } if (this.bitmap != null && this.bitmapIsCached && onImageEventListener!=null) { onImageEventListener.onPreviewReleased(); } this.bitmapIsPreview = false; this.bitmapIsCached = bitmapIsCached; this.bitmap = bitmap; this.sWidth = bitmap.getWidth(); this.sHeight = bitmap.getHeight(); this.sOrientation = sOrientation; boolean ready = checkReady(); boolean imageLoaded = checkImageLoaded(); if (ready || imageLoaded) { invalidate(); requestLayout(); } }
/** * Called by worker task when a tile has loaded. Redraws the view. */ private synchronized void onTileLoaded() { debug("onTileLoaded"); checkReady(); checkImageLoaded(); if (isBaseLayerReady() && bitmap != null) { if (!bitmapIsCached) { bitmap.recycle(); } bitmap = null; if (onImageEventListener != null && bitmapIsCached) { onImageEventListener.onPreviewReleased(); } bitmapIsPreview = false; bitmapIsCached = false; } invalidate(); }
/** * Enable or disable pan gesture detection. Disabling pan causes the image to be centered. Pan * can still be changed from code. * @param panEnabled true to enable panning, false to disable. */ public final void setPanEnabled(boolean panEnabled) { this.panEnabled = panEnabled; if (!panEnabled && vTranslate != null) { vTranslate.x = (getWidth()/2) - (scale * (sWidth()/2)); vTranslate.y = (getHeight()/2) - (scale * (sHeight()/2)); if (isReady()) { refreshRequiredTiles(true); invalidate(); } } }
invalidate(); return true;
initialiseBaseLayer(new Point(maxTileWidth, maxTileHeight)); invalidate(); requestLayout();
/** * Double tap zoom handler triggered from gesture detector or on touch, depending on whether * quick scale is enabled. */ private void doubleTapZoom(PointF sCenter, PointF vFocus) { if (!panEnabled) { if (sRequestedCenter != null) { // With a center specified from code, zoom around that point. sCenter.x = sRequestedCenter.x; sCenter.y = sRequestedCenter.y; } else { // With no requested center, scale around the image center. sCenter.x = sWidth()/2; sCenter.y = sHeight()/2; } } float doubleTapZoomScale = Math.min(maxScale, SubsamplingScaleImageView.this.doubleTapZoomScale); boolean zoomIn = (scale <= doubleTapZoomScale * 0.9) || scale == minScale; float targetScale = zoomIn ? doubleTapZoomScale : minScale(); if (doubleTapZoomStyle == ZOOM_FOCUS_CENTER_IMMEDIATE) { setScaleAndCenter(targetScale, sCenter); } else if (doubleTapZoomStyle == ZOOM_FOCUS_CENTER || !zoomIn || !panEnabled) { new AnimationBuilder(targetScale, sCenter).withInterruptible(false).withDuration(doubleTapZoomDuration).withOrigin(ORIGIN_DOUBLE_TAP_ZOOM).start(); } else if (doubleTapZoomStyle == ZOOM_FOCUS_FIXED) { new AnimationBuilder(targetScale, sCenter, vFocus).withInterruptible(false).withDuration(doubleTapZoomDuration).withOrigin(ORIGIN_DOUBLE_TAP_ZOOM).start(); } invalidate(); }
/** * Set the pan limiting style. See static fields. Normally {@link #PAN_LIMIT_INSIDE} is best, for image galleries. */ public final void setPanLimit(int panLimit) { if (!VALID_PAN_LIMITS.contains(panLimit)) { throw new IllegalArgumentException("Invalid pan limit: " + panLimit); } this.panLimit = panLimit; if (isReady()) { fitToBounds(true); invalidate(); } }
/** * Set the minimum scale type. See static fields. Normally {@link #SCALE_TYPE_CENTER_INSIDE} is best, for image galleries. */ public final void setMinimumScaleType(int scaleType) { if (!VALID_SCALE_TYPES.contains(scaleType)) { throw new IllegalArgumentException("Invalid scale type: " + scaleType); } this.minimumScaleType = scaleType; if (isReady()) { fitToBounds(true); invalidate(); } }
/** * Set scale, center and orientation from saved state. */ private void restoreState(ImageViewState state) { if (state != null && state.getCenter() != null && VALID_ORIENTATIONS.contains(state.getOrientation())) { this.orientation = state.getOrientation(); this.pendingScale = state.getScale(); this.sPendingCenter = state.getCenter(); invalidate(); } }