Android ImageView Skalierungs- und Übersetzungsproblem
Ich entwickle eine Android-Anwendung (API 19 4.4) und habe ein Problem mit ImageViews. Ich habe eine SurfaceView, in der ich dynamisch ImageViews hinzufüge, die ich auf Berührungsereignisse reagieren möchte. Bisher habe ich es geschafft, das ImageView reibungslos zu bewegen und zu skalieren, aber ich habe ein nerviges Verhalten.
Wenn ich das Bild auf eine bestimmte Grenze verkleinere (ich würde sagen, die Hälfte der Originalgröße) und versuche, es zu verschieben, flackert das Bild. Nach einer kurzen Analyse scheint es, als würde es seine Position symmetrisch um den Fingerpunkt auf dem Bildschirm verschieben, die Entfernung summieren und schließlich außer Sichtweite geraten (alles geschieht sehr schnell (<1s). Ich glaube, ich vermisse etwas mit dem Verwandten Wert des Berührungsereignisses auf die ImageView / SurfaceView, aber ich bin ein ziemlicher Neuling und stecke fest ...
Hier ist mein Code
public class MyImageView extends ImageView {
private ScaleGestureDetector mScaleDetector ;
private static final int MAX_SIZE = 1024;
private static final String TAG = "MyImageView";
PointF DownPT = new PointF(); // Record Mouse Position When Pressed Down
PointF StartPT = new PointF(); // Record Start Position of 'img'
public MyImageView(Context context) {
super(context);
mScaleDetector = new ScaleGestureDetector(context,new MySimpleOnScaleGestureListener());
setBackgroundColor(Color.RED);
setScaleType(ScaleType.MATRIX);
setAdjustViewBounds(true);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
lp.setMargins(-MAX_SIZE, -MAX_SIZE, -MAX_SIZE, -MAX_SIZE);
this.setLayoutParams(lp);
this.setX(MAX_SIZE);
this.setY(MAX_SIZE);
}
int firstPointerID;
boolean inScaling=false;
@Override
public boolean onTouchEvent(MotionEvent event) {
// get pointer index from the event object
int pointerIndex = event.getActionIndex();
// get pointer ID
int pointerId = event.getPointerId(pointerIndex);
//First send event to scale detector to find out, if it's a scale
boolean res = mScaleDetector.onTouchEvent(event);
if (!mScaleDetector.isInProgress()) {
int eid = event.getAction();
switch (eid & MotionEvent.ACTION_MASK)
{
case MotionEvent.ACTION_MOVE :
if(pointerId == firstPointerID) {
PointF mv = new PointF( (int)(event.getX() - DownPT.x), (int)( event.getY() - DownPT.y));
this.setX((int)(StartPT.x+mv.x));
this.setY((int)(StartPT.y+mv.y));
StartPT = new PointF( this.getX(), this.getY() );
}
break;
case MotionEvent.ACTION_DOWN : {
firstPointerID = pointerId;
DownPT.x = (int) event.getX();
DownPT.y = (int) event.getY();
StartPT = new PointF( this.getX(), this.getY() );
break;
}
case MotionEvent.ACTION_POINTER_DOWN: {
break;
}
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
case MotionEvent.ACTION_CANCEL: {
firstPointerID = -1;
break;
}
default :
break;
}
return true;
}
return true;
}
public boolean onScaling(ScaleGestureDetector detector) {
this.setScaleX(this.getScaleX()*detector.getScaleFactor());
this.setScaleY(this.getScaleY()*detector.getScaleFactor());
invalidate();
return true;
}
private class MySimpleOnScaleGestureListener extends SimpleOnScaleGestureListener {
@Override
public boolean onScale(ScaleGestureDetector detector) {
return onScaling(detector);
}
@Override
public boolean onScaleBegin(ScaleGestureDetector detector) {
Log.d(TAG, "onScaleBegin");
return true;
}
@Override
public void onScaleEnd(ScaleGestureDetector arg0) {
Log.d(TAG, "onScaleEnd");
}
}
}
Ich habe auch noch andere Fragen zu Rotationen. Wie soll ich das umsetzen? Kann ich den ScalegestureDetector auf irgendeine Weise verwenden oder muss ich dafür sorgen, dass dies im View-Touch-Ereignis funktioniert? Ich möchte in der Lage sein, in der gleichen Geste zu skalieren und zu drehen (und mich in einer anderen zu bewegen).
Vielen Dank für die Hilfe, ich würde mich sehr freuen!
Entschuldigung für mein Englisch