效果預(yù)覽
支持圖片的放大縮小宇弛,旋轉(zhuǎn)操作嫂拴。
原理實(shí)現(xiàn)
先認(rèn)識(shí)了解處理觸摸事件的處理。
- 以雙擊的位置為中心進(jìn)行放大縮小操作彼哼;
- 根據(jù)兩指之間的距離與初識(shí)距離距離比較,進(jìn)行放大和縮小操作湘今;
- 根據(jù)兩指之間的arctan值敢朱,計(jì)算角度進(jìn)行旋轉(zhuǎn)。
源碼實(shí)現(xiàn)
縮放:
@Override
public void setScale(float scale, float focalX, float focalY,
boolean animate) {
ImageView imageView = getImageView();
if (null != imageView) {
// Check to see if the scale is within bounds
if (scale < mMinScale || scale > mMaxScale) {
LogManager
.getLogger()
.i(LOG_TAG,
"Scale must be within the range of minScale and maxScale");
return;
}
if (animate) {
imageView.post(new AnimatedZoomRunnable(getScale(), scale,
focalX, focalY));
} else {
mSuppMatrix.setScale(scale, scale, focalX, focalY);
checkAndDisplayMatrix();
}
}
}
旋轉(zhuǎn):
private boolean doRotate(MotionEvent ev) {
//Calculate the angle between the two fingers
float deltaX = ev.getX(0) - ev.getX(1);
float deltaY = ev.getY(0) - ev.getY(1);
double radians = Math.atan(deltaY / deltaX);
//Convert to degrees
int degrees = (int) (radians * 180 / Math.PI);
/*
* Must use getActionMasked() for switching to pick up pointer events.
* These events have the pointer index encoded in them so the return
* from getAction() won't match the exact action constant.
*/
switch (ev.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
mLastAngle = degrees;
break;
case MotionEvent.ACTION_UP:
break;
case MotionEvent.ACTION_POINTER_DOWN:
mLastAngle = degrees;
break;
case MotionEvent.ACTION_POINTER_UP:
upRotate();
mLastAngle = degrees;
break;
case MotionEvent.ACTION_MOVE:
int degreesValue = degrees - mLastAngle;
if (degreesValue > 45) {
//Going CCW across the boundary
rotate(-5);
} else if (degreesValue < -45) {
//Going CW across the boundary
rotate(5);
} else {
//Normal rotation, rotate the difference
rotate(degreesValue);
}
//Save the current angle
mLastAngle = degrees;
break;
}
return true;
}
只貼了部分關(guān)鍵部分代碼摩瞎。