可以将整个ImageView(或者说整个View)在父布局里面移动,旋转,放大缩小
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
/**
* 整个ImageView的移动
* @author PanX
*/
public class CaptureView extends androidx.appcompat.widget.AppCompatImageView {
private int mode;
private final int NONE = -1;
private final int TRANSLATION = 0;
private final int SCALE = 1;
private float oldDist = 1;
private float mCurrSlope;
private float x1;
private float y1;
private float x2;
private float y2;
private int nOldLeft;
private int nOldTop;
private int nOldRight;
private int nOldBottom;
private int points;
private float rotation = 0;
private float newDist;
private Paint mPaint;
public CaptureView(Context context) {
super(context);
mPaint = new Paint();
mPaint.setColor(Color.BLUE);
mPaint.setAntiAlias(true); //抗锯齿
mPaint.setTextSize(30);
}
public CaptureView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
points = event.getPointerCount();
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_MOVE:
move(event);
break;
case MotionEvent.ACTION_POINTER_DOWN:
mode = SCALE;
oldDist = spacing(event);
nOldLeft = getLeft();
nOldTop = getTop();
nOldRight = getRight();
nOldBottom = getBottom();
break;
case MotionEvent.ACTION_DOWN:
mode = TRANSLATION;
break;
case MotionEvent.ACTION_UP:
mode = NONE;
break;
}
return true;
}
private void move(MotionEvent event) {
switch (mode) {
case TRANSLATION:
setX(event.getRawX() - getWidth() / 2);//直接移动X轴
setY(event.getRawY() - getHeight() / 2);//直接移动Y轴
break;
case SCALE:
//设置中心轴X、Y
setPivotX(getWidth() / 2);
setPivotY(getHeight() / 2);
//缩放
float tmpDist = spacing(event);
newDist = tmpDist;
float scale = newDist / oldDist;
scaleX(scale);
scaleY(scale);
//旋转
//原理:判断是不是不止一个触摸点,然后将每次移动的斜率加在总的斜率rotation里面,然后将其进行旋转
if (points > 1) {
mCurrSlope = caculateSlope(event);
}
setRotation(mCurrSlope + rotation);
rotation = mCurrSlope + rotation;
if (rotation > 180) {//特殊情况下避免数据越界,每±180度减回去,形成闭环
rotation = -180;
} else if (rotation < -180) {
rotation = 180;
}
break;
}
}
// 触碰两点间距离
private float spacing(MotionEvent event) {
if (event.getPointerCount() > 1) {
float x = event.getX(0) - event.getX(1);
float y = event.getY(0) - event.getY(1);
return (float) Math.abs(Math.sqrt(x * x + y * y));
} else {
return newDist;
}
}
/**
* 计算斜率y2-y1,x2-x1相当于直角三角形的两个直边
*
* @param event
* @return 只计算前两个触控点的斜率
*/
private float caculateSlope(MotionEvent event) {
x1 = event.getX(0);
y1 = event.getY(0);
x2 = event.getX(1);
y2 = event.getY(1);
return (y2 - y1) / (x2 - x1);
}
//x 倍率
public void scaleX(float n) {
int oldWidth = nOldRight - nOldLeft;
int count = (int) (oldWidth * (1 - n) / 2); //改变量
if (oldWidth - 2 * count >= 100) {
setLeft(nOldLeft + count);
setRight(nOldRight - count);
}
}
public void scaleY(float n) {
int oldHeight = nOldBottom - nOldTop;
int count = (int) (oldHeight * (1 - n) / 2); //改变量
if (oldHeight - 2 * count >= 100) {
setTop(nOldTop + count);
setBottom(nOldBottom - count);
}
}
}