我是ANDROID的新手,想要在我自己的自定义视图中旋转,缩放和移动图像。但我在同一个onTouchEvent方法中编写了所有这些(旋转,缩放,移动)。因此,当我移动图像时,它也会旋转或者我缩放图像,它会被移动。我必须单独处理它们但不知道如何处理它们。我想我可以添加一个按钮,例如哪个名称是“旋转”。所以我可以修复图像,它只允许旋转。但是我无法在自定义视图中创建按钮。代码如下所示:
public class MyView extends View {
// The ‘active pointer’ is the one currently moving our object.
private int mActivePointerId = INVALID_POINTER_ID;
private static final int INVALID_POINTER_ID = -1;
private ScaleGestureDetector mScaleDetector;
private float mScaleFactor = 1.f;
private float mPosX;
private float mPosY;
private float mLastTouchX;
private float mLastTouchY;
//For Fetching image
private Bitmap bmp;
private Drawable image;
private byte[] byteArray;
private ByteArrayBuffer baf = null;
//For Rotation
int direction = 0;
int degree = 0;
private float centerX ;
private float centerY ;
private float newX ;
private float newY ;
private float rotateX;
private float rotateY;
public MyView(Context context) {
this(context, null, 0);
}
public MyView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MyView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
String url = "http://www.queness.com/resources/images/png/apple_ex.png";
AsyncTask<String,Void,ByteArrayBuffer> connection=new GetUrlData().execute(url);
try {
baf=connection.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
byteArray = baf.toByteArray();
bmp = BitmapFactory.decodeByteArray(byteArray, 0 , byteArray.length);
image =new BitmapDrawable(context.getResources() , bmp);
image.setBounds(0, 0, image.getIntrinsicWidth(), image.getIntrinsicHeight());
mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(Color.BLACK);
//For Rotation
int height = this.getHeight();
int width = this.getWidth();
centerX = width/2;
centerY = height/2;
canvas.rotate(direction, width / 2, height / 2);
canvas.save();
canvas.translate(mPosX, mPosY);
canvas.scale(mScaleFactor, mScaleFactor);
image.draw(canvas);
canvas.restore();
}
//For Rotation
private void updateRotation(float newX2, float newY2) {
degree = (int)Math.toDegrees(Math.atan2(newY, newX))-90;
setDirection(degree);
}
//For Rotation
public void setDirection(int direction) {
this.direction = direction;
this.invalidate();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// Let the ScaleGestureDetector inspect all events.
mScaleDetector.onTouchEvent(event);
final int action = event.getAction();
if (action == MotionEvent.ACTION_DOWN) {
final float x = event.getX();
final float y = event.getY();
mLastTouchX = x;
mLastTouchY = y;
mActivePointerId = event.getPointerId(0);
}
if (action == MotionEvent.ACTION_MOVE) {
final int pointerIndex = event.findPointerIndex(mActivePointerId);
final float x = event.getX(pointerIndex);
final float y = event.getY(pointerIndex);
// Only move if the ScaleGestureDetector isn't processing a gesture.
if (!mScaleDetector.isInProgress()) {
final float dx = x - mLastTouchX;
final float dy = y - mLastTouchY;
mPosX += dx;
mPosY += dy;
invalidate();
}
mLastTouchX = x;
mLastTouchY = y;
//For Rotation
rotateX = event.getX();
rotateY = event.getY();
newX = centerX-rotateX;
newY = centerY-rotateY;
updateRotation( newX, newY);
}
if (action == MotionEvent.ACTION_UP) {
mActivePointerId = INVALID_POINTER_ID;
updateRotation( newX, newY);
}
if (action == MotionEvent.ACTION_CANCEL) {
mActivePointerId = INVALID_POINTER_ID;
}
if (action == MotionEvent.ACTION_POINTER_UP) {
final int pointerIndex = (event.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK)
>> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
final int pointerId = event.getPointerId(pointerIndex);
if (pointerId == mActivePointerId) {
// This was our active pointer going up. Choose a new
// active pointer and adjust accordingly.
final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
mLastTouchX = event.getX(newPointerIndex);
mLastTouchY = event.getY(newPointerIndex);
mActivePointerId = event.getPointerId(newPointerIndex);
}
}
return true;
}
private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
@Override
public boolean onScale(ScaleGestureDetector detector) {
mScaleFactor *= detector.getScaleFactor();
// Don't let the object get too small or too large.
mScaleFactor = Math.max(0.1f, Math.min(mScaleFactor, 5.0f));
invalidate();
return true;
}
}
}
我希望我能说出我想要的东西。你能帮帮我解决这个问题吗?
答案 0 :(得分:2)
尝试使用以下代码为我工作。
float[] lastEvent = null;
float d = 0f;
float newRot = 0f;
private Matrix matrix = new Matrix();
private Matrix savedMatrix = new Matrix();
public static String fileNAME;
public static int framePos = 0;
private float scale = 0;
private float newDist = 0;
// Fields
private String TAG = this.getClass().getSimpleName();
// We can be in one of these 3 states
private static final int NONE = 0;
private static final int DRAG = 1;
private static final int ZOOM = 2;
private int mode = NONE;
// Remember some things for zooming
private PointF start = new PointF();
private PointF mid = new PointF();
float oldDist = 1f;
public boolean onTouch(View v, MotionEvent event) {
ImageView view = (ImageView) v;
// Handle touch events here...
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
savedMatrix.set(matrix);
start.set(event.getX(), event.getY());
mode = DRAG;
lastEvent = null;
break;
case MotionEvent.ACTION_POINTER_DOWN:
oldDist = spacing(event);
if (oldDist > 10f) {
savedMatrix.set(matrix);
midPoint(mid, event);
mode = ZOOM;
}
lastEvent = new float[4];
lastEvent[0] = event.getX(0);
lastEvent[1] = event.getX(1);
lastEvent[2] = event.getY(0);
lastEvent[3] = event.getY(1);
d = rotation(event);
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
mode = NONE;
lastEvent = null;
break;
case MotionEvent.ACTION_MOVE:
if (mode == DRAG) {
// ...
matrix.set(savedMatrix);
matrix.postTranslate(event.getX() - start.x, event.getY()
- start.y);
} else if (mode == ZOOM && event.getPointerCount() == 2) {
float newDist = spacing(event);
matrix.set(savedMatrix);
if (newDist > 10f) {
float scale = newDist / oldDist;
matrix.postScale(scale, scale, mid.x, mid.y);
}
if (lastEvent != null) {
newRot = rotation(event);
float r = newRot - d;
matrix.postRotate(r, view.getMeasuredWidth() / 2,
view.getMeasuredHeight() / 2);
}
}
break;
}
view.setImageMatrix(matrix);
return true;
}
//用于多点触控旋转图像。
private float rotation(MotionEvent event) {
double delta_x = (event.getX(0) - event.getX(1));
double delta_y = (event.getY(0) - event.getY(1));
double radians = Math.atan2(delta_y, delta_x);
return (float) Math.toDegrees(radians);
}
private float spacing(MotionEvent event) {
float x = event.getX(0) - event.getX(1);
float y = event.getY(0) - event.getY(1);
return FloatMath.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 / 2, y / 2);
}