Leinwand Pinch-Zoom, um Punkt Innerhalb der Grenzen
Ich Hänge schon länger an diesem problem, für acht Stunden, so dass ich dachte, es war Zeit, etwas Hilfe zu bekommen.
Bevor ich anfange mein problem, ich werde einfach lassen Sie es bekannt sein, dass ich habe durch diese Website und Google, und keine der Antworten, die ich gefunden habe, geholfen haben. (Diese ist einer, ein weiteres, und ein weiteres.)
Hier ist der deal: ich habe eine Klasse, die Sie erweitert SurfaceView
(nennen wir es MySurface
) und überschreibt viele Verfahren in der it. Normalerweise zieht es mehrere Plätze und text-Boxen, das ist alles in Ordnung. Sobald ein Benutzer beginnt, berühren, verwandelt es sich um eine Bitmap
, dann zieht jeder frame, bis der Benutzer freigibt.
Hier ist der Haken: ich möchte, dass die Implementierung einer solchen Funktionalität kann der Benutzer legen Sie zwei Finger auf dem Bildschirm, Prise zu vergrößern und auch verschieben (aber NUR mit zwei Finger nach unten).
Fand ich ein paar Implementierungen von pinch-to-zoom und paßte Sie an, meine Canvas
Objekt in MySurface
über die folgenden:
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.save();
canvas.scale(mScaleVector.z, mScaleVector.z); //This is the scale factor as seen below
canvas.translate(mScaleVector.x, mScaleVector.y); //These are offset values from 0,0, both working fine
//Start draw code
//...
//End draw code
canvas.restore();
}
private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
@Override
public boolean onScale(ScaleGestureDetector detector) {
float factor = detector.getScaleFactor();
if (Math.abs(factor - 1.0f) >= 0.0075f) {
mScaleVector.z *= factor;
mScaleVector.z = Math.max(MIN_ZOOM, Math.min(mScaleVector.z, MAX_ZOOM));
}
//...
invalidate();
return true;
}
}
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction() & MotionEvent.ACTION_MASK;
int pointerIndex = (event.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
if (event.getPointerCount() == 2) {
if (action == MotionEvent.ACTION_POINTER_DOWN && pointerIndex == 1) {
//The various pivot coordinate codes would belong here
}
}
detector.onTouchEvent(event); //Calls the Scale Gesture Detector
return true;
}
Während beide Elemente funktionieren--das scrollen hin und her, und die pinch-to-zoom-es ist ein großes problem. Die pinch-to-zoom, wenn verwendet, zoomt auf den Punkt 0,0
statt Zoomen in die finger zeigen.
Ich habe versucht, eine Menge von Möglichkeiten, um dies zu beheben:
- Mit
canvas.scale(mScaleVector.z, mScaleVector.z, mScaleVector.x, mScaleVector.y);
; offensichtlich führt dies zu unerwünschten Ergebnissen wie diemScaleVector
x-und y-Werte sind 0-offsets. - Verwaltung einer "pivot" - Koordinate, die verwendet die gleiche offset wie die
translate()
Methode, aber dies führt entweder den gleichen0,0
Problem, oder herumspringen, wenn die Anzeige berührt wird. - Viele andere Dinge... ich habe eine Menge mit den oben genannten pivot-Koordinate, zu versuchen, um der Lage sein, seine Position auf den Vornamen des Benutzers berühren, und verschieben relativ zu berühren, aufeinander Geste.
Zusätzlich, diese Leinwand muss begrenzt werden, so dass der Benutzer nicht Blättern für immer. Jedoch, wenn ich den .scale(sx, sy, px, py)
Methode, schiebt er die Dinge, die jenseits jeglicher Grenzen, die ich gesetzt in .translate()
.
Ich bin... so ziemlich offen für alles an dieser Stelle. Ich kenne diese Funktionalität kann Hinzugefügt werden, wie es gesehen wird, in dem Android 4.0-Galerie (bei der Anzeige eines einzigen Bildes). Ich habe versucht, die Spur der Quelle-code, der verarbeitet diese, ohne Erfolg.
- Ich persönlich handle das zwei-finger-Positionen, die direkt mit der
onTouchEvent
. Mit diesem können Sie leicht finden Sie die Mitte-Punkt, und wie viel Skalierung erforderlich ist. - kannst du bitte die Lösung posten, wenn Sie haben das Problem gelöst, stehe ich vor demselben problem, und mein client ist.... : (oder können Sie mir sagen, wie Sie das problem lösen. danke
Du musst angemeldet sein, um einen Kommentar abzugeben.
Hier ist der code, den ich verwenden, um zu implementieren, pinch-zoom in einem
ImageView
mitScaleGestureDetector
. Mit wenig oder gar keine änderungen, die Sie sollten in der Lage sein, es zu benutzen zu, da Sie verwenden können, transformation marices auch das zeichnen auf einemCanvas
.In meinem Fall, ich berechnet die notwendigen Werte in die
onMeasure()
- Methode der Ansicht, Sie könnten dies tun wollen, irgendwo in IhremSurfaceView
Eine kleine Erklärung:
saveScale
ist der aktuelle Maßstab derBitmap
mScaleFactor
ist der Faktor, den Sie haben, multiplizieren Sie Ihre Waage-Verhältnis mit.maxScale
undminScale
können Konstante Werte sein.width
undheight
sind die Abmessungen des Bildschirms.redundantXSpace
undredundantYSpace
sind die leere zwischen den Bildrändern und der Bildschirm Grenzen, da das Bild zentriert ist, wenn in Sie ist kleiner, dann wird der BildschirmorigHeight
undorigWidth
sind die Größe der bitmapmatrix
ist die aktuelle Transformationsmatrix verwendet zum zeichnen der bitmapDer trick ist, dass wenn ich zuerst skaliert und zentriert das Bild auf die Initialisierung, die ich abgeholt, die Maßstab 1 und mit
scaleMappingRatio
ich zugeordnet die tatsächlichen Skalenwerte des Bildes relativ zu diesem.Dies ist monodroid code, aber kann leicht umgewandelt, um JAVA.
Sie können wählen, welche Werte für die gebundene (hier 50 Pixel Rand)