在Android實際項目開發中,經常要用到ImageView這個組件,如果純粹只是用來顯示某一張圖片,這個原生的組件是很方便的。但有時候爲了效果更炫一點,比如很多軟件都有的對圖片的處理,隨着手勢的變化來拉大或縮小圖片,這時就需要對原生的ImageView做一些處理來達到我們想要的效果。
原理就是Matrix 和PointF的運用,其實明白後一點都不難。我們需要寫一個類繼承ImageView來實現我們想要的功能,我這裏演示的是類名是:ScaleImageView ,主要是重寫onTouchEvent方法,去監聽手勢的變化,以此來對圖片進行處理。
不多說了,貼出來原理,複製過去就可以用了。
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.util.AttributeSet;
import android.util.FloatMath;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.ImageView;
@SuppressLint("FloatMath")
public class ScaleImageView extends ImageView {
private Matrix matrix=new Matrix();
private Matrix savedMatrix=new Matrix();
static final int NONE = 0;
static final int DRAG = 1;
static final int ZOOM = 2;
int mode = NONE;
// Remember some things for zooming
PointF start = new PointF();
PointF mid = new PointF();
float oldDist = 1f;
public ScaleImageView(Context context) {
super(context);
}
public ScaleImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public ScaleImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
private float spacing(MotionEvent event) {
float x = event.getX(0) - event.getX(1);
float y = event.getY(0) - event.getY(1);
return FloatMath.sqrt(x * x + y * y);
}
private void midPoint(PointF point, MotionEvent event) {
float x = event.getX(0) + event.getX(1);
float y = event.getY(0) + event.getY(1);
point.set(x / 2, y / 2);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if(event.getActionMasked()==MotionEvent.ACTION_POINTER_UP)
Log.d("Infor", "多點操作");
switch(event.getActionMasked()){
case MotionEvent.ACTION_DOWN:
matrix.set(getImageMatrix());
savedMatrix.set(matrix);
start.set(event.getX(),event.getY());
Log.d("Infor", "觸摸了...");
mode=DRAG;
break;
case MotionEvent.ACTION_POINTER_DOWN: //多點觸控
oldDist=this.spacing(event);
if(oldDist>10f){
Log.d("Infor", "oldDist"+oldDist);
savedMatrix.set(matrix);
midPoint(mid,event);
mode=ZOOM;
}
break;
case MotionEvent.ACTION_POINTER_UP:
mode=NONE;
break;
case MotionEvent.ACTION_MOVE:
if(mode==DRAG){ //此實現圖片的拖動功能...
matrix.set(savedMatrix);
matrix.postTranslate(event.getX()-start.x, event.getY()-start.y);
}
else if(mode==ZOOM){// 此實現圖片的縮放功能...
float newDist=spacing(event);
if(newDist>10){
matrix.set(savedMatrix);
float scale=newDist/oldDist;
matrix.postScale(scale, scale, mid.x, mid.y);
}
}
break;
}
setImageMatrix(matrix);
return true;
}
}
這個類寫好之後,用法和原生的ImageView一樣,只是這樣之後可以實現圖片的縮放,而且不用再做任何處理。用法如下:
這裏特別要注意的是 android:scaleType="matrix" 這一行配置,scaleType 一定要是 matrix 類型的,否則就會失效,凡是要實現這類效果的,一定要設置成matrix類型的。
好了,到這裏,關於ImageView對圖片的動態縮放的實現就OK了。