直接上代码
<cn.weijian.sweeping_robot.widget.MatrixImageView
android:layout_above="@id/robot_bottom_layout"
android:id="@+id/slamware_map_image_view"
android:scaleType="matrix"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:src="@drawable/map"/>
package cn.weijian.sweeping_robot.widget;
import android.content.Context;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
//import android.support.v7.widget.AppCompatImageView;
import android.widget.ImageView;
import androidx.annotation.Nullable;
import cn.weijian.sweeping_robot.utils.ViewUtils;
public class MatrixImageView extends ImageView {
private static final String TAG = MatrixImageView.class.getSimpleName();
private Matrix currentMatrix = new Matrix();
private Matrix savedMatrix = new Matrix();
private PointF startF = new PointF();
private PointF midF = new PointF();
private float oldDis = 1f; // 初始的两个手指按下的触摸点的距离
private float saveRotate = 0F; // 保存了的角度值
private static final int MODE_NONE = 0; // 默认的触摸模式
private static final int MODE_DRAG = 1; // 拖拽模式
private static final int MODE_ZOOM = 2; // 缩放模式
private int mode = MODE_NONE;
private int ddx=0, ddy=0;
private float dScale = 1;
public MatrixImageView(Context context) {
super(context);
init();
}
public MatrixImageView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
public MatrixImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
public MatrixImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init();
}
private void init(){
Log.e(TAG, "width: "+getWidth()+", height: "+getHeight());
setOnLongClickListener(new OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
return true;
}
});
setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
ImageView view = (ImageView)v;
switch (event.getAction()& MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:// 单点接触屏幕时
savedMatrix.set(currentMatrix);
startF.set(event.getX(), event.getY());
mode=MODE_DRAG;
break;
case MotionEvent.ACTION_POINTER_DOWN:// 第二个手指按下事件
oldDis = ViewUtils.calDis(event);
if (oldDis > 10F) {
savedMatrix.set(currentMatrix);
midF = ViewUtils.calMidPoint(event);
mode = MODE_ZOOM;
}
saveRotate = ViewUtils.calRotation(event);//计算初始的角度
break;
case MotionEvent.ACTION_MOVE:// 触摸点移动时
if (mode == MODE_DRAG) {
// 单点触控拖拽平移
float dx = event.getX() - startF.x;
float dy = event.getY() - startF.y;
startF.set(event.getX(), event.getY());
// if(Math.abs(ddx+dx)<=view.getWidth()*dScale && Math.abs(ddy+dy)<=view.getHeight()*dScale)
{
ddx+=dx;
ddy+=dy;
currentMatrix.postTranslate(dx, dy);
}
}
else if(mode == MODE_ZOOM && event.getPointerCount() == 2){
// 两点触控拖放
float newDis = ViewUtils.calDis(event);
float rotate = ViewUtils.calRotation(event);
//指尖移动距离大于10F缩放
if (newDis > 10F){
float scale = newDis / oldDis;
oldDis = newDis;
if(scale*dScale<10 && scale*dScale>0.1){
dScale *= scale;
currentMatrix.postScale(scale, scale, midF.x, midF.y);
Log.e(TAG, "dScale: "+dScale+", scale: "+scale);
}
}
//当旋转的角度大于5F才进行旋转
if(Math.abs(rotate - saveRotate)>1F){
currentMatrix.postRotate(rotate - saveRotate, view.getWidth() / 2, view.getHeight() / 2);
saveRotate = rotate;
Log.e(TAG, "saveRotate: "+saveRotate+", rotate: "+rotate);
}
}
break;
case MotionEvent.ACTION_UP:// 单点离开屏幕时
mode=MODE_NONE;
break;
case MotionEvent.ACTION_POINTER_UP:// 第二个点离开屏幕时
savedMatrix.set(currentMatrix);
if(event.getActionIndex()==0)
startF.set(event.getX(1), event.getY(1));
else if(event.getActionIndex()==1)
startF.set(event.getX(0), event.getY(0));
mode=MODE_DRAG;
break;
}
view.setImageMatrix(currentMatrix);
return false;
}
});
}
public Matrix getCurrentMatrix() {
return currentMatrix;
}
public Matrix getSavedMatrix() {
return savedMatrix;
}
public float getSaveRotate() {
return saveRotate;
}
}