RotatableImageView in Android
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
public class RotatableImageView extends ImageView {
private float mRotationDegrees = 0f;
private float mFocusX = 0f;
private float mFocusY = 0f;
private Matrix mMatrix = new Matrix();
private Matrix mSavedMatrix = new Matrix();
private boolean mIsRotating = false;
public RotatableImageView(Context context) {
super(context);
init();
}
public RotatableImageView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public RotatableImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
setScaleType(ScaleType.MATRIX);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mIsRotating = false;
mSavedMatrix.set(mMatrix);
mFocusX = event.getX();
mFocusY = event.getY();
break;
case MotionEvent.ACTION_MOVE:
float dx = event.getX() - mFocusX;
float dy = event.getY() - mFocusY;
if (!mIsRotating) {
if (Math.abs(dx) > 10 || Math.abs(dy) > 10) {
mIsRotating = true;
}
}
if (mIsRotating) {
mMatrix.set(mSavedMatrix);
float degrees = (float) Math.toDegrees(Math.atan2(dy, dx));
mMatrix.postRotate(degrees - mRotationDegrees, getMeasuredWidth() / 2f, getMeasuredHeight() / 2f);
setImageMatrix(mMatrix);
}
break;
case MotionEvent.ACTION_UP:
if (mIsRotating) {
mRotationDegrees = (mRotationDegrees + 360f) % 360f;
}
break;
}
return true;
}
@Override
protected void onDraw(Canvas canvas) {
canvas.save();
canvas.rotate(mRotationDegrees, getMeasuredWidth() / 2f, getMeasuredHeight() / 2f);
super.onDraw(canvas);
canvas.restore();
}
public void rotate(float degrees) {
mMatrix.postRotate(degrees, getMeasuredWidth() / 2f, getMeasuredHeight() / 2f);
setImageMatrix(mMatrix);
}
public void setRotationDegrees(float degrees) {
mMatrix.postRotate(degrees - mRotationDegrees, getMeasuredWidth() / 2f, getMeasuredHeight() / 2f);
mRotationDegrees = degrees;
setImageMatrix(mMatrix);
}
public float getRotationDegrees() {
return mRotationDegrees;
}
}