imageview 放大旋转自定义 不能超出屏幕
时间: 2023-10-01 12:06:01 浏览: 83
你可以使用 Android 中的 Matrix 类来实现 ImageView 的放大和旋转,同时确保不超出屏幕的范围。以下是一个示例:
```java
public class ZoomRotateImageView extends androidx.appcompat.widget.AppCompatImageView {
private Matrix mMatrix = new Matrix();
private float mScaleFactor = 1.f;
private float mRotationDegrees = 0.f;
private float mFocusX = 0.f;
private float mFocusY = 0.f;
private int mImageWidth;
private int mImageHeight;
private int mViewWidth;
private int mViewHeight;
public ZoomRotateImageView(Context context) {
super(context);
init(context);
}
public ZoomRotateImageView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public ZoomRotateImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
private void init(Context context) {
setScaleType(ScaleType.MATRIX);
}
@Override
protected boolean setFrame(int l, int t, int r, int b) {
mViewWidth = r - l;
mViewHeight = b - t;
mMatrix.reset();
mMatrix.setTranslate((mViewWidth - mImageWidth) / 2f, (mViewHeight - mImageHeight) / 2f);
float scale = Math.min((float) mViewWidth / (float) mImageWidth, (float) mViewHeight / (float) mImageHeight);
mMatrix.postScale(scale, scale, mViewWidth / 2f, mViewHeight / 2f);
mMatrix.postRotate(mRotationDegrees, mViewWidth / 2f, mViewHeight / 2f);
setImageMatrix(mMatrix);
mScaleFactor = 1f;
return super.setFrame(l, t, r, b);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
mMatrix.set(getImageMatrix());
mFocusX = event.getX();
mFocusY = event.getY();
break;
case MotionEvent.ACTION_MOVE:
float dx = event.getX() - mFocusX;
float dy = event.getY() - mFocusY;
mMatrix.postTranslate(dx, dy);
setImageMatrix(mMatrix);
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
break;
case MotionEvent.ACTION_POINTER_DOWN:
float oldDistance = spacing(event);
if (oldDistance > 10f) {
mMatrix.set(getImageMatrix());
midPoint(mPointF, event);
}
break;
case MotionEvent.ACTION_MOVE | MotionEvent.ACTION_POINTER_DOWN:
float newDistance = spacing(event);
if (newDistance > 10f) {
mMatrix.set(getImageMatrix());
float scale = newDistance / oldDistance;
mMatrix.postScale(scale, scale, mPointF.x, mPointF.y);
mScaleFactor *= scale;
setImageMatrix(mMatrix);
}
break;
}
return true;
}
private PointF mPointF = new PointF();
private float spacing(MotionEvent event) {
float x = event.getX(0) - event.getX(1);
float y = event.getY(0) - event.getY(1);
return (float) Math.sqrt(x * x + y * y);
}
private void midPoint(PointF point, MotionEvent event) {
float x = event.getX(0) + event.getX(1);
float y = event.getY(0) + event.getY(1);
point.set(x / 2f, y / 2f);
}
public void setImageBitmap(Bitmap bm) {
super.setImageBitmap(bm);
mImageWidth = bm.getWidth();
mImageHeight = bm.getHeight();
}
public void setRotationDegrees(float degrees) {
mRotationDegrees = degrees;
invalidate();
}
}
```
这个自定义控件使用了 Matrix 类来处理 ImageView 的变换,包括平移、缩放和旋转。在 onTouchEvent() 中,我们只需要检测触摸事件的类型,然后更新相应的变换矩阵即可。在 setFrame() 中,我们会重新计算图片的缩放比例,并且确保图片不会超出屏幕的范围。你可以根据自己的需求修改代码来适应不同的场景。
阅读全文