自定义图片缩放组件—ImageZoomView
注:该文章为(男人应似海)原创,如需转载请注明出处!
组件功能
实现图片的手势缩放和移动
效果图
说明:效果图中下方得放大缩小组件是Android系统自带的组件ZoomControls,这里为了看上去美观和实现点击该组件放大图片,所以加上了该组件。点击图片时会隐藏该组件实现全屏浏览,具体实现请查看后面的代码。
实现方式
利用Java观察者模式实现(具体请查看java文章文章“java观察者模式介绍”),共包括三个类,它们的名称和功能分别是:
(1)ImageZoomView.java :该类继承了View类,相当于观察者,随状态改变更新图片显示。
(2)ImageZoomState.java :相当于被观察者,记录图片缩放和移动等状态。
(3)SimpleImageZoomListener.java:这个类继承了View的OnTouchListener接口,相当于一个协调者,工作方式是:监听ImageZoomView上的手势动作------->根据手势改变ImageZoomState的值并调用notifyObservers()方法通知ImageZoomView(观察者)执行update()方法------->update()方法调用ImageZoomView的 invalidate()方法,该方法会自动调用onDraw()方法重绘图像更新图片显示。
代码
ImageZoomView.java
public class ImageZoomView extends View implements Observer {
private Paint mPaint = new Paint(Paint.FILTER_BITMAP_FLAG);
private Rect mRectSrc = new Rect();
private Rect mRectDst = new Rect();
private float mAspectQuotient;
private Bitmap mBitmap;
private ImageZoomState mZoomState;
public ImageZoomView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public void update(Observable observable, Object data) {
this.invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
if (mBitmap != null && mZoomState != null) {
int viewWidth = this.getWidth();
int viewHeight = this.getHeight();
int bitmapWidth = mBitmap.getWidth();
int bitmapHeight = mBitmap.getHeight();
float panX = mZoomState.getmPanX();
float panY = mZoomState.getmPanY();
float zoomX = mZoomState.getZoomX(mAspectQuotient) * viewWidth
/ bitmapWidth;// 相当于viewHeight/bitmapHeight*mZoom
float zoomY = mZoomState.getZoomY(mAspectQuotient) * viewHeight
/ bitmapHeight;// 相当于viewWidth/bitmapWidth*mZoom
// Setup source and destination rectangles
// 这里假定图片的高和宽都大于显示区域的高和宽,如果不是在下面做调整
mRectSrc.left = (int) (panX * bitmapWidth - viewWidth / (zoomX * 2));
mRectSrc.top = (int) (panY * bitmapHeight - viewHeight
/ (zoomY * 2));
mRectSrc.right = (int) (mRectSrc.left + viewWidth / zoomX);
mRectSrc.bottom = (int) (mRectSrc.top + viewHeight / zoomY);
mRectDst.left = this.ge