写一个textureview多点触控,可以移动放大缩小图片和旋转的例子
时间: 2023-12-10 11:41:41 浏览: 159
好的,以下是一个简单的例子,演示了如何在TextureView上实现多点触控,包括移动、缩放和旋转图片:
```
public class MultiTouchTextureView extends TextureView {
private static final int INVALID_POINTER_ID = -1;
private Bitmap mBitmap;
private Matrix mMatrix;
private float mLastTouchX;
private float mLastTouchY;
private float mPosX;
private float mPosY;
private float mLastRotation;
private float mRotation = 0f;
private float mLastTouchDistance;
private float mTouchCenterX;
private float mTouchCenterY;
private int mActivePointerId = INVALID_POINTER_ID;
public MultiTouchTextureView(Context context) {
super(context);
init();
}
public MultiTouchTextureView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public MultiTouchTextureView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
mMatrix = new Matrix();
setSurfaceTextureListener(surfaceTextureListener);
}
private SurfaceTextureListener surfaceTextureListener = new SurfaceTextureListener() {
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, int height) {
// Load bitmap and set initial matrix
mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.sample_image);
mMatrix.setTranslate((getWidth() - mBitmap.getWidth()) / 2f, (getHeight() - mBitmap.getHeight()) / 2f);
invalidate();
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int width, int height) {
// Update matrix when view size changes
mMatrix.setTranslate((getWidth() - mBitmap.getWidth()) / 2f, (getHeight() - mBitmap.getHeight()) / 2f);
invalidate();
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
// Release resources
mBitmap.recycle();
return true;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
// Nothing to do
}
};
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN: {
int pointerIndex = event.getActionIndex();
float x = event.getX(pointerIndex);
float y = event.getY(pointerIndex);
mLastTouchX = x;
mLastTouchY = y;
mActivePointerId = event.getPointerId(pointerIndex);
break;
}
case MotionEvent.ACTION_MOVE: {
int pointerIndex = event.findPointerIndex(mActivePointerId);
if (pointerIndex != -1) {
float x = event.getX(pointerIndex);
float y = event.getY(pointerIndex);
// Multi-touch drag
if (event.getPointerCount() > 1) {
float distance = getDistance(event);
if (mLastTouchDistance != 0f) {
float scale = distance / mLastTouchDistance;
mMatrix.postScale(scale, scale, mTouchCenterX, mTouchCenterY);
}
mLastTouchDistance = distance;
float centerX = getCenterX(event);
float centerY = getCenterY(event);
if (mTouchCenterX != 0f && mTouchCenterY != 0f) {
float translateX = centerX - mTouchCenterX;
float translateY = centerY - mTouchCenterY;
mMatrix.postTranslate(translateX, translateY);
}
mTouchCenterX = centerX;
mTouchCenterY = centerY;
// Multi-touch rotation
float rotation = getRotation(event);
if (mLastRotation != 0f) {
float angle = rotation - mLastRotation;
mMatrix.postRotate(angle, mTouchCenterX, mTouchCenterY);
mRotation += angle;
}
mLastRotation = rotation;
}
// Single-touch drag
else {
float dx = x - mLastTouchX;
float dy = y - mLastTouchY;
mMatrix.postTranslate(dx, dy);
mPosX += dx;
mPosY += dy;
}
mLastTouchX = x;
mLastTouchY = y;
invalidate();
}
break;
}
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP: {
int pointerIndex = event.getActionIndex();
int pointerId = event.getPointerId(pointerIndex);
if (pointerId == mActivePointerId) {
// Reset values when the active pointer is lifted
mLastTouchDistance = 0f;
mLastRotation = 0f;
mTouchCenterX = 0f;
mTouchCenterY = 0f;
mActivePointerId = INVALID_POINTER_ID;
}
break;
}
}
return true;
}
private float getDistance(MotionEvent event) {
float dx = event.getX(0) - event.getX(1);
float dy = event.getY(0) - event.getY(1);
return (float) Math.sqrt(dx * dx + dy * dy);
}
private float getCenterX(MotionEvent event) {
float x1 = event.getX(0);
float x2 = event.getX(1);
return (x1 + x2) / 2f;
}
private float getCenterY(MotionEvent event) {
float y1 = event.getY(0);
float y2 = event.getY(1);
return (y1 + y2) / 2f;
}
private float getRotation(MotionEvent event) {
float dx = event.getX(0) - event.getX(1);
float dy = event.getY(0) - event.getY(1);
return (float) Math.toDegrees(Math.atan2(dy, dx));
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mBitmap != null) {
canvas.drawBitmap(mBitmap, mMatrix, null);
}
}
}
```
在这个例子中,我们使用了一个Matrix对象来保存图像的变换信息,并在触摸事件的处理方法中更新Matrix对象。我们可以使用Matrix对象的postScale()、postTranslate()和postRotate()方法来实现缩放、移动和旋转操作。
注意,在多点触控中,我们需要使用MotionEvent对象的getX(int)、getY(int)、getPointerCount()、getPointerId(int)、findPointerIndex(int)等方法来获取各个触摸点的坐标和标识等信息。我们还需要使用数学公式来计算出触摸点的中心位置、距离和角度等信息。
阅读全文