Ich erstelle eine Zeichen-App, und ich habe eine Ansicht, die eine Leinwand zum Zeichnen verwendet. Ich skaliere das Bild mit einer Matrix, und wenn das Bild vergrößert wird und ein Berührungsereignis eintritt, versuche ich, die Inverse der Matrix zu erhalten und mappe die Punkte dann mit der inversen Matrix, um die Punkte auf der Leinwand zu erhalten Das motionevent zeigt, aber es stimmt nicht überein, wie es sollte, und frage mich, was ich falsch mache, um den Canvas-Ort vom Bildschirm Touch-Ort zu bekommen.Erhalte die Position auf der Leinwand von der Position des Bewegungsereignisses, wenn sie mit der Matrix skaliert wird
public class CustomDrawableView extends View {
private Paint mBitmapPaint;
private ShapeDrawable mDrawable;
private ScaleGestureDetector detector;
Matrix drawMatrix;
Bitmap bm;
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.save();
canvas.drawBitmap(bm, drawMatrix, mBitmapPaint);
mDrawable.draw(canvas);
canvas.restore();
}
public Pair<Float,Float> GetRealValues(float eventX, float eventY){
Matrix inverse = new Matrix();
drawMatrix.invert(inverse);
float[] point = {eventX,eventY};
inverse.mapPoints(point);
return new Pair<>(point[0],point[1]);
}
@Override
//reads motions and calls methods to set starting and ending points and to
//draw canvas depending on the motion
public boolean onTouchEvent(MotionEvent event) {
//get the canvas location from the MotionEvent location
Pair<Float,Float> realvals = GetRealValues(event.getX(),event.getY());
//drawing mode where you can draw or zoom in on canvas
if(drawing) {
//not zooming mode where you draw on canvas
if (!zoom) {
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
//do stuff
break;
case MotionEvent.ACTION_MOVE:
//do stuff
break;
case MotionEvent.ACTION_UP:
//do stuff
break;
case MotionEvent.ACTION_POINTER_UP:
break;
}
}
//zoom mode where you can scale the canvas
if (zoom) {
detector.onTouchEvent(event);
invalidate();
}
}
return true;
}
public class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
private float MIN_ZOOM = 1f;
private float MAX_ZOOM = 10f;
@Override
public boolean onScale(ScaleGestureDetector detector) {
Matrix transformationMatrix = new Matrix();
scaleFactor *= detector.getScaleFactor();
float tscale = detector.getScaleFactor();
if(scaleFactor < MIN_ZOOM || scaleFactor > MAX_ZOOM){
float prescaleFactor = scaleFactor/tscale;
scaleFactor = Math.max(MIN_ZOOM, Math.min(scaleFactor, MAX_ZOOM));
tscale = scaleFactor/prescaleFactor;
}
transformationMatrix.postScale(tscale, tscale);
drawMatrix.postConcat(transformationMatrix);
return true;
}
}