matrix.postTranslate
时间: 2023-10-11 15:05:29 浏览: 106
matrix.postTranslate() 是一个在 Android 中使用的方法,它的作用是将一个矩阵对象进行平移变换。
具体来说,它接受两个参数,分别是平移的水平和垂直距离。例如,如果有一个矩阵对象 matrix,我们想要将它向右平移 100 个像素,向下平移 50 个像素,那么可以这样调用:
```
matrix.postTranslate(100, 50);
```
调用完之后,原来的矩阵对象 matrix 就会被修改,变成了一个进行了平移变换后的新矩阵。
需要注意的是,postTranslate() 方法是在当前矩阵的基础上进行平移变换的,因此如果之前已经进行了其他的变换操作,比如旋转或缩放,那么这些操作也会被保留下来。
相关问题
请优化代码,以下代码无法释放焦点 ,不能变换拖动目标 public boolean onTouchEvent(MotionEvent event) { switch (event.getAction() & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: // 手指压下屏幕 mode = MODE.DRAG; // 寻找被点击的图片 CustomBitmap clickedBitmap = null; for (CustomBitmap bitmap : _bitmaps) { float[] values = new float[9]; bitmap.matrix.getValues(values); float globalX = values[Matrix.MTRANS_X]; float globalY = values[Matrix.MTRANS_Y]; float width = values[Matrix.MSCALE_X] * bitmap.getBitmap().getWidth(); float height = values[Matrix.MSCALE_Y] * bitmap.getBitmap().getWidth(); Rect rect = new Rect((int) globalX, (int) globalY, (int) (globalX + width), (int) (globalY + height)); if (rect.contains((int) event.getX(), (int) event.getY())) { clickedBitmap = bitmap; break; } } // 切换操作对象 if (clickedBitmap != null) { _bitmaps.remove(clickedBitmap); _bitmaps.add(clickedBitmap); currentMatrix.set(clickedBitmap.matrix);// 记录ImageView当前的移动位置 clickedBitmap.matrix.set(currentMatrix); clickedBitmap.startPoint.set(event.getX(), event.getY()); _curCustomBitmap = clickedBitmap; } postInvalidate(); break; case MotionEvent.ACTION_POINTER_DOWN: // 当屏幕上还有触点(手指),再有一个手指压下屏幕 mode = MODE.ZOOM; _curCustomBitmap.oldRotation = rotation(event); _curCustomBitmap.startDis = distance(event); if (_curCustomBitmap.startDis > 10f) { _curCustomBitmap.midPoint = mid(event); currentMatrix.set(_curCustomBitmap.matrix);// 记录ImageView当前的缩放倍数 } break; case MotionEvent.ACTION_MOVE: // 手指在屏幕移动,该事件会不断地触发 if (mode == MODE.DRAG) { float dx = event.getX() - _curCustomBitmap.startPoint.x;// 得到在x轴的移动距离 float dy = event.getY() - _curCustomBitmap.startPoint.y;// 得到在y轴的移动距离 _curCustomBitmap.matrix.set(currentMatrix);// 在没有进行移动之前的位置基础上进行移动 _curCustomBitmap.matrix.postTranslate(dx, dy); } else if (mode == MODE.ZOOM) {// 缩放与旋转 float endDis = distance(event);// 结束距离 _curCustomBitmap.rotation = rotation(event) - _curCustomBitmap.oldRotation; if (endDis > 10f) { float scale = endDis / _curCustomBitmap.startDis;// 得到缩放倍数 _curCustomBitmap.matrix.set(currentMatrix); _curCustomBitmap.matrix.postScale(scale, scale, _curCustomBitmap.midPoint.x, _curCustomBitmap.midPoint.y); _curCustomBitmap.matrix.postRotate(_curCustomBitmap.rotation, _curCustomBitmap.midPoint.x, _curCustomBitmap.midPoint.y); } } break; case MotionEvent.ACTION_UP: // 手指离开屏 break; case MotionEvent.ACTION_POINTER_UP: // 有手指离开屏幕,但屏幕还有触点(手指) mode = MODE.NONE; break; } invalidate(); return true; }
以下是对代码的优化建议:
1. 将对位图的操作封装成一个方法,以提高可读性和可维护性。
2. 在ACTION_DOWN事件中,可以使用MotionEvent的findPointerIndex()和getX()、getY()方法来获取点击位置,避免使用循环查找位图。
3. 在ACTION_MOVE事件中,可以使用Matrix的postTranslate()和postScale()方法来进行位图的移动和缩放,避免重复创建Matrix对象。
4. 在ACTION_POINTER_DOWN事件中,可以使用MotionEvent的getX()、getY()方法来获取缩放中心点的坐标,避免重复计算。
5. 在ACTION_POINTER_DOWN事件中,可以将记录位图旋转角度和缩放倍数的代码提取出来,避免与缩放和旋转的代码耦合。
6. 在ACTION_POINTER_UP事件中,可以将模式设置为MODE.NONE,避免在其他事件中误操作。
7. 在代码中添加注释,以提高可读性和可维护性。
下面是优化后的代码:
```
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
// 手指压下屏幕
mode = MODE.DRAG;
// 查找被点击的图片
int index = event.getActionIndex();
float x = event.getX(index);
float y = event.getY(index);
CustomBitmap clickedBitmap = findClickedBitmap(x, y);
if (clickedBitmap != null) {
// 切换操作对象
_bitmaps.remove(clickedBitmap);
_bitmaps.add(clickedBitmap);
// 记录ImageView当前的移动位置
currentMatrix.set(clickedBitmap.matrix);
clickedBitmap.matrix.set(currentMatrix);
clickedBitmap.startPoint.set(x, y);
_curCustomBitmap = clickedBitmap;
}
postInvalidate();
break;
case MotionEvent.ACTION_POINTER_DOWN:
// 当屏幕上还有触点(手指),再有一个手指压下屏幕
mode = MODE.ZOOM;
// 记录位图的旋转角度和缩放倍数
_curCustomBitmap.oldRotation = rotation(event);
_curCustomBitmap.startDis = distance(event);
if (_curCustomBitmap.startDis > 10f) {
// 获取缩放中心点的坐标
float x1 = event.getX(0);
float y1 = event.getY(0);
float x2 = event.getX(1);
float y2 = event.getY(1);
_curCustomBitmap.midPoint.set((x1 + x2) / 2, (y1 + y2) / 2);
// 记录ImageView当前的缩放倍数
currentMatrix.set(_curCustomBitmap.matrix);
}
break;
case MotionEvent.ACTION_MOVE:
// 手指在屏幕移动,该事件会不断地触发
if (mode == MODE.DRAG) {
// 移动图片
float dx = event.getX() - _curCustomBitmap.startPoint.x;
float dy = event.getY() - _curCustomBitmap.startPoint.y;
_curCustomBitmap.matrix.set(currentMatrix);
_curCustomBitmap.matrix.postTranslate(dx, dy);
} else if (mode == MODE.ZOOM) {
// 缩放和旋转图片
float endDis = distance(event);
float rotation = rotation(event) - _curCustomBitmap.oldRotation;
if (endDis > 10f) {
float scale = endDis / _curCustomBitmap.startDis;
_curCustomBitmap.matrix.set(currentMatrix);
_curCustomBitmap.matrix.postScale(scale, scale, _curCustomBitmap.midPoint.x, _curCustomBitmap.midPoint.y);
_curCustomBitmap.matrix.postRotate(rotation, _curCustomBitmap.midPoint.x, _curCustomBitmap.midPoint.y);
}
}
break;
case MotionEvent.ACTION_POINTER_UP:
// 有手指离开屏幕,但屏幕还有触点(手指)
mode = MODE.NONE;
break;
}
invalidate();
return true;
}
// 查找被点击的图片
private CustomBitmap findClickedBitmap(float x, float y) {
for (CustomBitmap bitmap : _bitmaps) {
float[] values = new float[9];
bitmap.matrix.getValues(values);
float globalX = values[Matrix.MTRANS_X];
float globalY = values[Matrix.MTRANS_Y];
float width = values[Matrix.MSCALE_X] * bitmap.getBitmap().getWidth();
float height = values[Matrix.MSCALE_Y] * bitmap.getBitmap().getHeight();
RectF rect = new RectF(globalX, globalY, globalX + width, globalY + height);
if (rect.contains(x, y)) {
return bitmap;
}
}
return null;
}
// 计算两点之间的距离
private float distance(MotionEvent event) {
float x1 = event.getX(0);
float y1 = event.getY(0);
float x2 = event.getX(1);
float y2 = event.getY(1);
return (float) Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}
// 计算两点之间的旋转角度
private float rotation(MotionEvent event) {
float x1 = event.getX(0);
float y1 = event.getY(0);
float x2 = event.getX(1);
float y2 = event.getY(1);
double radians = Math.atan2(y2 - y1, x2 - x1);
return (float) Math.toDegrees(radians);
}
```
下段代码 可以拖动,但缩放和旋转时会闪退,请改正 public boolean onTouchEvent(MotionEvent event) { switch (event.getAction() & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: // 手指压下屏幕 mode = MODE.DRAG; // 查找被点击的图片 int index = event.getActionIndex(); float x = event.getX(index); float y = event.getY(index); CustomBitmap clickedBitmap = findClickedBitmap(x, y); if (clickedBitmap != null) { // 切换操作对象 _bitmaps.remove(clickedBitmap); _bitmaps.add(clickedBitmap); // 记录ImageView当前的移动位置 currentMatrix.set(clickedBitmap.matrix); clickedBitmap.matrix.set(currentMatrix); clickedBitmap.startPoint.set(x, y); _curCustomBitmap = clickedBitmap; } postInvalidate(); break; case MotionEvent.ACTION_POINTER_DOWN: // 当屏幕上还有触点(手指),再有一个手指压下屏幕 mode = MODE.ZOOM; // 记录位图的旋转角度和缩放倍数 _curCustomBitmap.oldRotation = rotation(event); _curCustomBitmap.startDis = distance(event); if (_curCustomBitmap.startDis > 10f) { // 获取缩放中心点的坐标 float x1 = event.getX(0); float y1 = event.getY(0); float x2 = event.getX(1); float y2 = event.getY(1); _curCustomBitmap.midPoint.set((x1 + x2) / 2, (y1 + y2) / 2); // 记录ImageView当前的缩放倍数 currentMatrix.set(_curCustomBitmap.matrix); } break; case MotionEvent.ACTION_MOVE: // 手指在屏幕移动,该事件会不断地触发 if (mode == MODE.DRAG) { // 移动图片 float dx = event.getX() - _curCustomBitmap.startPoint.x; float dy = event.getY() - _curCustomBitmap.startPoint.y; _curCustomBitmap.matrix.set(currentMatrix); _curCustomBitmap.matrix.postTranslate(dx, dy); } else if (mode == MODE.ZOOM) { // 缩放和旋转图片 float endDis = distance(event); float rotation = rotation(event) - _curCustomBitmap.oldRotation; if (endDis > 10f) { float scale = endDis / _curCustomBitmap.startDis; _curCustomBitmap.matrix.set(currentMatrix); _curCustomBitmap.matrix.postScale(scale, scale, _curCustomBitmap.midPoint.x, _curCustomBitmap.midPoint.y); _curCustomBitmap.matrix.postRotate(rotation, _curCustomBitmap.midPoint.x, _curCustomBitmap.midPoint.y); } } break; case MotionEvent.ACTION_POINTER_UP: // 有手指离开屏幕,但屏幕还有触点(手指) mode = MODE.NONE; break; } invalidate(); return true;
可能是因为在缩放和旋转时,没有判断当前操作的图片是否为null,导致空指针异常。可以在缩放和旋转的代码之前添加判断,如果当前操作的图片为空,就直接返回。修改后的代码如下:
```
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
// 手指压下屏幕
mode = MODE.DRAG;
// 查找被点击的图片
int index = event.getActionIndex();
float x = event.getX(index);
float y = event.getY(index);
CustomBitmap clickedBitmap = findClickedBitmap(x, y);
if (clickedBitmap != null) {
// 切换操作对象
_bitmaps.remove(clickedBitmap);
_bitmaps.add(clickedBitmap);
// 记录ImageView当前的移动位置
currentMatrix.set(clickedBitmap.matrix);
clickedBitmap.matrix.set(currentMatrix);
clickedBitmap.startPoint.set(x, y);
_curCustomBitmap = clickedBitmap;
}
postInvalidate();
break;
case MotionEvent.ACTION_POINTER_DOWN:
// 当屏幕上还有触点(手指),再有一个手指压下屏幕
mode = MODE.ZOOM;
// 记录位图的旋转角度和缩放倍数
if (_curCustomBitmap == null) {
return true;
}
_curCustomBitmap.oldRotation = rotation(event);
_curCustomBitmap.startDis = distance(event);
if (_curCustomBitmap.startDis > 10f) {
// 获取缩放中心点的坐标
float x1 = event.getX(0);
float y1 = event.getY(0);
float x2 = event.getX(1);
float y2 = event.getY(1);
_curCustomBitmap.midPoint.set((x1 + x2) / 2, (y1 + y2) / 2);
// 记录ImageView当前的缩放倍数
currentMatrix.set(_curCustomBitmap.matrix);
}
break;
case MotionEvent.ACTION_MOVE:
// 手指在屏幕移动,该事件会不断地触发
if (mode == MODE.DRAG) {
// 移动图片
if (_curCustomBitmap == null) {
return true;
}
float dx = event.getX() - _curCustomBitmap.startPoint.x;
float dy = event.getY() - _curCustomBitmap.startPoint.y;
_curCustomBitmap.matrix.set(currentMatrix);
_curCustomBitmap.matrix.postTranslate(dx, dy);
} else if (mode == MODE.ZOOM) {
// 缩放和旋转图片
if (_curCustomBitmap == null) {
return true;
}
float endDis = distance(event);
float rotation = rotation(event) - _curCustomBitmap.oldRotation;
if (endDis > 10f) {
float scale = endDis / _curCustomBitmap.startDis;
_curCustomBitmap.matrix.set(currentMatrix);
_curCustomBitmap.matrix.postScale(scale, scale, _curCustomBitmap.midPoint.x, _curCustomBitmap.midPoint.y);
_curCustomBitmap.matrix.postRotate(rotation, _curCustomBitmap.midPoint.x, _curCustomBitmap.midPoint.y);
}
}
break;
case MotionEvent.ACTION_POINTER_UP:
// 有手指离开屏幕,但屏幕还有触点(手指)
mode = MODE.NONE;
break;
}
invalidate();
return true;
}
```
阅读全文