Android使用SubsamplingScaleImageView完美查看超大图片
Android使用SubsamplingScaleImageView完美查看超大图片
一、目标
在神马笔记中查看《溪山清远图》。
二、体验地址
神马笔记最新版本下载:【神马笔记 版本2.2.0——功能优化.apk】
三、实现方案
1. SubsamplingScaleImageView
在《Android加载超大图片》一文中,我们已经介绍过SubsamplingScaleImageView
的基础用法。
这里结合SubsamplingScaleImageView
的功能来提高图片浏览体验。
2. OnStateChangedListener
使用OnStateChangedListener
可以监听到SubsamplingScaleImageView
的缩放和移动事件。
2D图片有3个维度的操作:
- 位置——移动图片
- 大小——缩放图片
- 角度——旋转图片
SubsamplingScaleImageView
不支持第3个维度——角度。
因此只有移动和缩放2个事件。
通过OnStateChangedListener
,我们可以实现当用户进行缩放或者移动,或者2者同时发生时,自动全屏。
全屏之后,图片变不会被菜单栏所遮挡,可以看到全部图片。
/**
* An event listener, allowing activities to be notified of pan and zoom events. Initialisation
* and calls made by your code do not trigger events; touch events and animations do. Methods in
* this listener will be called on the UI thread and may be called very frequently - your
* implementation should return quickly.
*/
@SuppressWarnings("EmptyMethod")
public interface OnStateChangedListener {
/**
* The scale has changed. Use with {@link #getMaxScale()} and {@link #getMinScale()} to determine
* whether the image is fully zoomed in or out.
* @param newScale The new scale.
* @param origin Where the event originated from - one of {@link #ORIGIN_ANIM}, {@link #ORIGIN_TOUCH}.
*/
void onScaleChanged(float newScale, int origin);
/**
* The source center has been changed. This can be a result of panning or zooming.
* @param newCenter The new source center point.
* @param origin Where the event originated from - one of {@link #ORIGIN_ANIM}, {@link #ORIGIN_TOUCH}.
*/
void onCenterChanged(PointF newCenter, int origin);
}
3. setDoubleTapZoomScale
通过setDoubleTapZoomScale
接口,可以设置双击图片的缩放系数。
因为SubsamplingScaleImageView
初始显示时,使整张图片居中显示。即最长的一边完全显示在屏幕内。
因此,我们设置双击图片时,将最短的一边完全显示在屏幕内。
并且当长宽比一致时,设置为2倍大小。
static float getDoubleTapScale(int width, int height, int viewWidth, int viewHeight) {
if (viewWidth <= 0 || viewHeight <= 0) {
return 1;
}
float sx = viewWidth * 1.f / width;
float sy = viewHeight * 1.f / height;
float scale = Math.max(sx, sy);
if (Math.abs(sx - sy) < Float.MIN_NORMAL) {
scale = 2 * sx;
}
return scale;
}
四、Finally
~倚遍阑干~只是无情绪~