这会涉及到两个知识点:
1、Matrix对象:Matrix是一个3*3的矩阵,里面封装了9个float数值,通过控制这9个数值,可以控制图片的大小、旋转、位置、倾斜等。
2、Android的事件处理机制
有两种:基于监听的事件处理机制;基于回调的事件处理机制。
事件处理的先后顺序:1、触发组件绑定的事件监听器;2、触发组件提供的回调方法;3、传播到该组件所在的Activity。其中的返回值代表着事件是否被消费,如果为true,则被消费,即事件不会继续向外传播。
事件对象:MotionEvent。
单指拖拽:
Matrix matrix = new Matrix();
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case (MotionEvent.ACTION_DOWN):
//这样写的话第一次能拖拽,但是之后就不能拖拽了
// matrix = img_test.getImageMatrix();
//拿取图片当前的matrix
matrix.set(img_test.getImageMatrix());
//拿取按下点的坐标
startPoint.set(event.getX(), event.getY());
break;
case (MotionEvent.ACTION_MOVE):
//用setTranslate的话拖拽不动
// matrix.setTranslate(event.getX() - startPoint.x, event.getY() - startPoint.y);
//拿取移动后的点的坐标,和之前点的坐标比较,计算在这次移动中,横纵坐标各移动了多少。
//然后将图像的matrix对象也移动这么多。
matrix.postTranslate(event.getX() - startPoint.x, event.getY() - startPoint.y);
//在一次移动结束后,将移动起始点的坐标更新
startPoint.set(event.getX(), event.getY());
break;
}
//在一次移动后,将根据移动后更新的matrix对象设置到ImageView上,以更新图像的位置
img_test.setImageMatrix(matrix);
//将此次事件消费
return true;
}
双指缩放:
//无任何手势模式
public static final int NONE = 0;
//缩放模式
public static final int SCALE = 1;
//当前处在什么模式
int mode = NONE;
//图片的matrix对象
Matrix matrix = new Matrix();
//未缩放前两指之间的距离
float startDistance = 0f;
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case (MotionEvent.ACTION_POINTER_DOWN):
//拿取图片当前的matrix
matrix.set(img_test.getImageMatrix());
//拿取当前两指间的距离
startDistance = distance(event);
//两指同时按下时,进入缩放模式
mode = SCALE;
break;
case (MotionEvent.ACTION_MOVE):
//当此时为缩放模式时
if (mode == SCALE) {
//拿取缩放后两指之间的距离
float distance = distance(event);
//和缩放前两指间的距离比较,计算出缩放比例
float scale = distance / startDistance;
//按照手势的缩放比例,将图片的matrix对象也缩放这么多
matrix.postScale(scale, scale);
//在一次缩放后,将初始的两指间距离设置为当前的两指间距离
startDistance = distance;
}
break;
case (MotionEvent.ACTION_UP):
case (MotionEvent.ACTION_POINTER_UP):
//一只手指抬起或者两只手指抬起时,进入无任何手势模式
mode = NONE;
break;
}
//在一次缩放后,将更新后的matrix对象设置到图片上,从而使图片能够即时的缩放
img_test.setImageMatrix(matrix);
//将此次事件消费
return true;
}