// 用于处理缩放的工具类,用法与GestureDetector类似,都是通过onTouchEvent关联相应的MotionEvent。
// 使用该类时,用户需要拆入一个完整的连续不断的motion事件(包含ACTION_DOWN,ACTION_MOVE和ACTION_UP事件)
final ScaleGestureDetector scaleGestureDetector = new ScaleGestureDetector(this,
new ScaleGestureDetector.OnScaleGestureListener() {
// 缩放时。返回值代表本次缩放事件是否已被处理。如果已被处理,那么detector就会
// 重置缩放事件;如果未被处理,detector会计算进行计算,修改getScaleFactor()的返回
// 值,知道被处理为止。因此,它常用在判断只有缩放值达到一定数值时才进行缩放。例如
@Override
public boolean onScale(ScaleGestureDetector detector) {
Log.i(TAG, "onScale facotr = " +detector.getScaleFactor());
//if(detector.getScaleFactor() < 2) {
// return false;
//}
// mMatrix.preScale(detector.getScaleFactor(), detector.getScaleFactor())
// setImageMatrix(mMaxtrix)
/**
* 可以看出getScaleFactor返回的值由小变大,直到大于2后又从1开始变大。这是因为
* 当缩放因子(getScaleFactor的返回值)小于2时,onScale返回的时false,此时
* detector认为本次缩放尚未结束,所以本次计算缩放因子时仍旧以上次结束时为准,
* 这样就导致了手指外移时搜房参数越来越大;当达到2后,本次缩放结束,再次获得缩放因子时
* 的基准就变成刚刚结束的为止了,因此,获取的缩放因子会猛然变小(因为手指外移,执行的是
* 放大操作,所以缩放因子会大于1)。
*/
return true;
}
// 缩放开始,该detector是否处理候后继的缩放事件。返回false时,不会执行onScale
@Override
public boolean onScaleBegin(ScaleGestureDetector detector) {
return false;
}
@Override
public void onScaleEnd(ScaleGestureDetector detector) {
// 缩放结束时
}
}
);
//获取本次缩放事件的缩放因子(缩放事件以onScale)返回值为基准,一旦该方法返回true,
//代表本次事件结束,要开启下次事件)。它的返回值时指本次事件中的缩放值,并不是相对于开始的值。
//如一张图片开始放大2倍,后来又放到1.1 倍。那么第二次放大时,该方法返回的就是1.1,
//而不是总放大倍数:2*1.1
scaleGestureDetector.getScaleFactor();
//返回手势过程中,组成该手势的两个触点的当前距离。返回值以像素为单位的触点距离。
scaleGestureDetector.getCurrentSpan();
//跟getCurrentSpan()类似,只不过一个是返回的是x轴上的距离,一个是y轴上的距离。
//注意:返回值有可能为负数。这两个方法的返回值和getCurrentSpan()的返回值满足勾股定理。
scaleGestureDetector.getCurrentSpanX();
scaleGestureDetector.getCurrentSpanY();
//返回组成该手势的两个触点的中点在组件上的y,x轴坐标,单位为像素。
scaleGestureDetector.getFocusX();
scaleGestureDetector.getFocusY();
//返回缩放过程中,组成当前缩放手势的两个触点的前一次距离。
//假设有a,b,c三个手指,某一次a,b组成缩放手势,两者的距离是300;随后一直是b,c组成缩放手势,当c抬起时,b,c的距离时100。
//此时,ab会组成缩放手势,该值返回的就是300,而不是b,c的100。
scaleGestureDetector.getPreviousSpan();
scaleGestureDetector.getPreviousSpanX();
scaleGestureDetector.getPreviousSpanY();
//获取当前motion事件的时间
//mCurrTime = event.getEventTime();//该方法返回的就是mCurrTime的
scaleGestureDetector.getEventTime();
//返回上次缩放事件结束时到当前的时间间隔
scaleGestureDetector.getTimeDelta();
//如果缩放手势正处在进行中,返回true;否则返回false。
scaleGestureDetector.isInProgress();
recyclerView.setOnTouchListener(new View.OnTouchListener() {
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouch(View v, MotionEvent event) {
scaleGestureDetector.onTouchEvent(event);
//gestureDetector.onTouchEvent(event);
return true;
}
});
实例
public class TestScaleActivity extends AppCompatActivity {
private SurfaceView mSurfaceView;
private ScaleGestureDetector mGestureDetector;
private Bitmap bitmap;
private SurfaceHolder mSurfaceHolder;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test_scale);
mSurfaceView = findViewById(R.id.mSurfaceView);
mSurfaceHolder = mSurfaceView.getHolder();
mGestureDetector = new ScaleGestureDetector(this, new MyScaleGestureListener());
// 点击按钮
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
//锁定整个SurfaceView
Canvas mCanvas = mSurfaceHolder.lockCanvas();
//画图
mCanvas.drawBitmap(bitmap, 0f, 0f, null);
//绘制完成,提交修改
mSurfaceHolder.unlockCanvasAndPost(mCanvas);
//重新锁定一次
mSurfaceHolder.lockCanvas(new Rect(0, 0, 0, 0));
mSurfaceHolder.unlockCanvasAndPost(mCanvas);
}
});
}
@Override
public boolean onTouchEvent(MotionEvent event) {
return mGestureDetector.onTouchEvent(event);
}
public class MyScaleGestureListener implements ScaleGestureDetector.OnScaleGestureListener {
@Override
public boolean onScale(ScaleGestureDetector detector) {
Matrix matrix = new Matrix();
//缩放比例
float scale = detector.getScaleFactor() / 3;
matrix.setScale(scale, scale);
// 锁定整个Sureface
Canvas mCanvas = mSurfaceHolder.lockCanvas();
//清屏
mCanvas.drawColor(Color.BLACK);
//画缩放后的图
mCanvas.drawBitmap(bitmap, matrix, null);
// 绘制完成,提交修改
mSurfaceHolder.unlockCanvasAndPost(mCanvas);
//重新锁一次
mSurfaceHolder.lockCanvas(new Rect(0,0,0,0));
mSurfaceHolder.unlockCanvasAndPost(mCanvas);
return false;
}
@Override
public boolean onScaleBegin(ScaleGestureDetector detector) {
// 一定要返回true才会进入onScale这个函数
return true;
}
@Override
public void onScaleEnd(ScaleGestureDetector detector) {
}
}
}