前几天做项目用到相机拍照,之后能对图片进行缩放,拖拽,在此我将其单独抽取出来,后面用到时直接拿来用就行了!
效果图:
注:这里不仅能按钮缩放,还能多点触摸缩放和拖拽功能!
1.布局:
<?xml version="1.0" encoding="UTF-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/flayout_img_display"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<LinearLayout
android:id="@+id/linearLayout_img_display"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center"
android:gravity="center" >
<ImageView
android:id="@+id/img_display"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingBottom="5.0dip"
android:paddingTop="5.0dip"
android:scaleType="matrix" />
</LinearLayout>
<RelativeLayout
android:id="@+id/relativeLayout1"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<Button
android:id="@+id/btn_min"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:enabled="false"
android:text="缩小" />
<Button
android:id="@+id/btn_out"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:text="放大" />
</RelativeLayout>
</FrameLayout>
2.就一个类:
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.os.Bundle;
import android.util.FloatMath;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
/**
* 缩放图片界面
* @author ZHF
*
*/
public class MainActivity extends Activity {
public static final String TAG = "ImgDisplayActivity";
//控件声明
private Button btnZoomin, btnZoomout;
private ImageView imgDisPlay;
private LinearLayout lLayoutDisplay;
private FrameLayout fLayoutDisplay;
private Bitmap bitmap;
private int imgId = 0;
private double scale_in = 0.8;//缩小比例
private double scale_out = 1.25;//放大比例
private float scaleWidth = 1;
private float scaleHeight = 1;
//模式:0:什么都不干;1:拖拽; 2:缩放
public static final int NONE = 0;
public static final int DRAG = 1;
public static final int ZOOM = 2;
//声明触发的事件模式
private int mode = NONE;
private Matrix matrix; //矩阵
private Matrix currMatrix; //当前矩阵
private PointF starPoint;
private PointF midPoint;
private float startDistance;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//初始化
fLayoutDisplay = (FrameLayout) findViewById(R.id.flayout_img_display);
lLayoutDisplay = (LinearLayout) findViewById(R.id.linearLayout_img_display);
imgDisPlay = (ImageView) findViewById(R.id.img_display);
btnZoomin = (Button) findViewById(R.id.btn_min);
btnZoomout = (Button) findViewById(R.id.btn_out);
matrix = new Matrix(); //保存拖拽变化
currMatrix = new Matrix();// 当前的
starPoint = new PointF();//开始点的位置
btnZoomin.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
zoomIn();
}
});
btnZoomout.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
zoomOut();//放大
}
});
imgDisPlay.setImageResource(R.drawable.img);
//给图片绑定监听器哦
imgDisPlay.setOnTouchListener(new ImageViewOnTouchListener());
}
/**放大操作**/
private void zoomOut() {
reSizeBmp(scale_out);
btnZoomin.setEnabled(true);
}
/**缩小操作**/
private void zoomIn() {
reSizeBmp(scale_in);
}
/**接收传入的缩放比例实现缩放**/
private void reSizeBmp(double scale) {
//缩放比例
scaleWidth = (float) (scaleWidth * scale);
scaleHeight = (float) (scaleHeight * scale);
Matrix matrix = new Matrix();
matrix.postScale(scaleWidth, scaleHeight); //设计缩放比例
imgDisPlay.setImageMatrix(matrix);
}
/**计算触摸实现缩放**/
final class ImageViewOnTouchListener implements OnTouchListener{
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN: //一只手指按下
Log.i(TAG,"一只手指按下");
currMatrix.set(matrix);
starPoint.set(event.getX(), event.getY());
mode = DRAG;
break;
case MotionEvent.ACTION_POINTER_DOWN: //如果有一只手指按下屏幕,后续又有一个手指按下 // 两只手指按下
Log.i(TAG,"又有一只手指按下");
startDistance = distance(event);//记下两点的距离
Log.i(TAG, startDistance+"");
if(startDistance > 5f) { //两个手指之间的最小距离像素大于5,认为是多点触摸
mode = ZOOM;
currMatrix.set(matrix);
midPoint = getMidPoint(event); //记下两个点之间的中心点
}
break;
case MotionEvent.ACTION_MOVE:
if(mode == DRAG) { //拖拽模式
Log.i(TAG,"一只手指在拖拽");
//开始--》结束点的距离
float dx = event.getX() - starPoint.x;
float dy = event.getY() - starPoint.y;
matrix.set(currMatrix);
matrix.postTranslate(dx, dy);//移动到指定点:矩阵移动比例;eg:缩放有缩放比例
} else if(mode == ZOOM) { //缩放模式
Log.i(TAG,"正在缩放");
float distance = distance(event); //两点之间的距离
if(distance > 5f) {
matrix.set(currMatrix);
float cale = distance / startDistance;
matrix.preScale(cale, cale, midPoint.x, midPoint.y); //进行比例缩放
}
}
break;
case MotionEvent.ACTION_UP: //最后一只手指离开屏幕后触发此事件
case MotionEvent.ACTION_POINTER_UP: //一只手指离开屏幕,但还有一只手指在上面会触此事件
//什么都没做
mode = NONE;
break;
default:
break;
}
imgDisPlay.setImageMatrix(matrix);
//两只手指的缩放
return true;
}
}
/**计算两点之间的距离像素**/
private float distance(MotionEvent e) {
float eX = e.getX(1) - e.getX(0); //后面的点坐标 - 前面点的坐标
float eY = e.getY(1) - e.getY(0);
return FloatMath.sqrt(eX * eX + eY * eY);
}
/**计算两点之间的中心点**/
private PointF getMidPoint(MotionEvent event) {
float x = (event.getX(1) - event.getX(0)) / 2;
float y = (event.getY(1) - event.getY(0)) / 2;
return new PointF(x,y);
}
}
ok!主要的算法就在ImageViewOnTouchListener监听器当中,要考虑那三种情况(缩放、拖拽、什么都不干),另外需要注意的就是,单个手指和两个以上手指的情况。
×××:http://down.51cto.com/data/876165