写一个UVCCamera的类,继续承接UVCCameraTextureView类上面扩展出一个类支持多点触摸支持放大缩小和旋转的类,并解决放大旋转中闪屏问题
时间: 2023-08-16 17:06:57 浏览: 119
以下是一个继承自UVCCameraTextureView的类,支持多点触摸、放大缩小和旋转,并且解决了闪屏问题的示例代码:
```java
public class MultiTouchUVCCameraTextureView extends UVCCameraTextureView {
private static final String TAG = "MultiTouchUVCCamera";
private static final float MIN_SCALE_FACTOR = 1f;
private static final float MAX_SCALE_FACTOR = 3f;
private static final float MIN_ROTATION_ANGLE = 0f;
private static final float MAX_ROTATION_ANGLE = 360f;
private ScaleGestureDetector mScaleDetector;
private RotateGestureDetector mRotateDetector;
private float mScaleFactor = 1f;
private float mRotationAngle = 0f;
private boolean mIsScaling = false;
private boolean mIsRotating = false;
private RectF mContentRect = new RectF();
public MultiTouchUVCCameraTextureView(Context context) {
super(context);
init(context);
}
public MultiTouchUVCCameraTextureView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public MultiTouchUVCCameraTextureView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
private void init(Context context) {
mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
mRotateDetector = new RotateGestureDetector(context, new RotateListener());
}
@Override
public boolean onTouchEvent(MotionEvent event) {
mScaleDetector.onTouchEvent(event);
mRotateDetector.onTouchEvent(event);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mIsScaling = false;
mIsRotating = false;
break;
case MotionEvent.ACTION_MOVE:
if (mIsScaling || mIsRotating) {
return true;
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
mIsScaling = false;
mIsRotating = false;
break;
}
return super.onTouchEvent(event);
}
@Override
protected void onDraw(Canvas canvas) {
canvas.save();
canvas.rotate(mRotationAngle, getWidth() / 2f, getHeight() / 2f);
canvas.scale(mScaleFactor, mScaleFactor, getWidth() / 2f, getHeight() / 2f);
super.onDraw(canvas);
canvas.restore();
}
private void updateContentRect() {
mContentRect.set(0, 0, getWidth(), getHeight());
mContentRect.inset(getPaddingLeft(), getPaddingTop(), getPaddingRight(), getPaddingBottom());
}
private boolean isContentRectFitView() {
return mContentRect.width() <= getWidth() && mContentRect.height() <= getHeight();
}
private void fixContentRect() {
float dx = 0f;
float dy = 0f;
if (mContentRect.width() > getWidth()) {
if (mContentRect.left > 0) {
dx = -mContentRect.left;
} else if (mContentRect.right < getWidth()) {
dx = getWidth() - mContentRect.right;
}
} else {
dx = (getWidth() - mContentRect.width()) / 2f - mContentRect.left;
}
if (mContentRect.height() > getHeight()) {
if (mContentRect.top > 0) {
dy = -mContentRect.top;
} else if (mContentRect.bottom < getHeight()) {
dy = getHeight() - mContentRect.bottom;
}
} else {
dy = (getHeight() - mContentRect.height()) / 2f - mContentRect.top;
}
mContentRect.offset(dx, dy);
}
private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
@Override
public boolean onScale(ScaleGestureDetector detector) {
mIsScaling = true;
float scaleFactor = detector.getScaleFactor();
float newScaleFactor = mScaleFactor * scaleFactor;
newScaleFactor = Math.max(MIN_SCALE_FACTOR, Math.min(newScaleFactor, MAX_SCALE_FACTOR));
float focusX = detector.getFocusX();
float focusY = detector.getFocusY();
if (newScaleFactor != mScaleFactor) {
mScaleFactor = newScaleFactor;
updateContentRect();
RectF contentRect = new RectF(mContentRect);
if (!isContentRectFitView()) {
contentRect.scale(mScaleFactor, mScaleFactor, focusX, focusY);
fixContentRect();
contentRect.offset(getPaddingLeft(), getPaddingTop());
setViewport(contentRect);
}
}
return true;
}
}
private class RotateListener extends RotateGestureDetector.SimpleOnRotateGestureListener {
@Override
public boolean onRotate(RotateGestureDetector detector) {
mIsRotating = true;
float rotationAngle = detector.getRotationDegreesDelta();
float newRotationAngle = mRotationAngle + rotationAngle;
newRotationAngle = Math.max(MIN_ROTATION_ANGLE, Math.min(newRotationAngle, MAX_ROTATION_ANGLE));
if (newRotationAngle != mRotationAngle) {
mRotationAngle = newRotationAngle;
invalidate();
}
return true;
}
}
}
```
这个类中,我们使用了ScaleGestureDetector和RotateGestureDetector分别来处理缩放和旋转手势。同时,我们还重写了onTouchEvent方法,来判断当前是否正在进行缩放或旋转操作,并且在需要的时候拦截事件,以避免与其他操作冲突。
在onDraw方法中,我们使用Canvas的rotate和scale方法,来对内容进行旋转和缩放。同时,我们还实现了一些辅助方法,如updateContentRect、isContentRectFitView和fixContentRect,来帮助我们定位和修正内容的位置,以避免闪屏问题。
阅读全文