Ich verwende ZoomLayout, um Hoch- / Querformatbilder anzuzeigen. Ich habe Zoom & OverScroll deaktiviert. Ich verwende horizontales und vertikales Pan nur mit CenterCrop. Es kann wie erwartet nur in eine Richtung geschwenkt werden (da Zoom deaktiviert ist). Dadurch kann ich einen Teil des Bildes anzeigen, während der andere Teil mit Pan angezeigt werden kann.
Wie ich verstanden habe, funktioniert centercrop, indem entweder containerHeight
an childHeight
oder containerWidth
an childWidth
. Rechts? Stellen Sie sich vor, Bilder im Quer-/Hochformat in eine quadratische ImageView zu laden. Bei Bildern im Querformat wird childHeight
mit containerHeight
, um Centercrop auszuführen, und jetzt kann das Schwenken horizontal ausgeführt werden. Ebenso kann bei Hochformatbildern das Schwenken vertikal durchgeführt werden.
Dies funktioniert gut.
Wenn ich jedoch die Breite/Höhe von ZoomLayout so ändere, wird die Transformation nicht auf die untergeordnete Ansicht angewendet.
val layoutParams = zoomLayout.layoutParams
layoutParams.width = layoutParams.width + changedWidth
layoutParams.height = layoutParams.height + changedHeight
zoomLayout.layoutParams = layoutParams
Schritte zum Reproduzieren des Verhaltens, ggf. in der Demo-App:
Wenn sich die Containerhöhe ändert, wird eine untergeordnete Transformation angewendet, um CenterCrop beizubehalten.
init {
setHorizontalPanEnabled(true)
setVerticalPanEnabled(true)
setOverScrollHorizontal(false)
setOverScrollVertical(false)
setAlignment(Alignment.TOP or Alignment.LEFT)
setHasClickableChildren(true)
setTransformation(
ZoomApi.TRANSFORMATION_CENTER_CROP,
ZoomApi.TRANSFORMATION_GRAVITY_AUTO
)
setZoomEnabled(false)
}
Gestartet
I/ZoomLayout: setHasClickableChildren: old: false new: false
I/ZoomLayout: setHasClickableChildren: old: false new: true
Horizontalen Hintergrund laden, der auf Kind gezeichnet werden kann.
W/ZoomEngine: onMatrixSizeChanged: firstTime: true oldZoom: NaN transformation: 1 transformationZoom: 0.0
I/ZoomEngine: computeTransformationZoom centerCrop scaleX: 1.0042135 scaleY: 5.860656
I/ZoomEngine: onMatrixSizeChanged: newTransformationZoom: 5.860656 newRealZoom: 5.8606563 newZoom: 1.0000001
Erhöhen Sie die ZoomLayout-Höhe mit dem obigen Code.
W/ZoomEngine: onMatrixSizeChanged: firstTime: false oldZoom: 5.8606563 transformation: 1 transformationZoom: 5.860656
I/ZoomEngine: computeTransformationZoom centerCrop scaleX: 1.0042135 scaleY: 6.2704916
I/ZoomEngine: onMatrixSizeChanged: newTransformationZoom: 6.2704916 newRealZoom: 5.8606563 newZoom: 0.93464065
Das Kind wird nicht transformiert, um die Centercrop-Funktionalität beizubehalten.
Wird bei Bedarf zur Verfügung gestellt, aber sehr einfach zu verwendende Reproduktionsschritte.
Ich habe den folgenden Code verwendet, um dies zu umgehen.
val layoutParams = zoomLayout.layoutParams
layoutParams.width = layoutParams.width + changedWidth
layoutParams.height = layoutParams.height + changedHeight
zoomLayout.layoutParams = layoutParams
zoomLayout.engine.setContainerSize(
layoutParams.width.toFloat(),
layoutParams.height.toFloat(),
applyTransformation = false // not applying transformation
)
Und eine weitere Änderung in ZoomLayouts onGlobalLayout()
engine.setContentSize(
child.width.toFloat(),
child.height.toFloat(),
applyTransformation = true // <-- this change
)
Dies hilft mir. Das Kind ist korrekt mit dem Elternteil ausgerichtet, um die Centercrop-Funktionalität beizubehalten. Aber dieser Code bringt das Problem #185 hervor. Jetzt kenne ich eindeutig den Grund, warum Pan zurückgesetzt wird (hint#global-layout).
Ich suche also immer noch nach einer Möglichkeit, ZoomLayout anzuweisen, die Transformation auf das Kind anzuwenden, wenn die Breite/Höhe des Containers geändert wird. Wenn ich weiter versuche, Hacks zu verwenden, werde ich nur noch mehr Fehler haben. Sie haben daran gearbeitet, Sie wissen es besser als ich. Bitte führen Sie mich.
Vielen Dank für den ausführlichen Bericht.
Ich denke, dies ist ein allgemeines Problem, bei dem ZoomLayout noch kein wirklich definiertes Verhalten beim Ändern der Abmessungen des Containers hat, da wir erwarten, dass der Container seine Abmessungen beibehält. Bitte korrigieren Sie mich, wenn ich falsch liege @natario1. So wie ich es verstehe, ist dies eher eine Funktionsanfrage als ein Fehler.
Wenn wir dies unterstützen wollen, müssen wir meiner Meinung nach eine Diskussion darüber führen, wie das erwartete Verhalten aussehen soll und wie Entwickler davon abweichen können.
Ich mag, wie es gerade funktioniert, die Containergröße kann sich aus vielen Gründen ändern, und wenn der Inhalt bereits gezoomt/geschwenkt wurde, sollten wir die Transformation meiner Meinung nach nicht erneut anwenden. Sie sollten in der Lage sein, das zu erreichen, was Sie möchten, wie folgt:
zoomLayout.layoutParams = layoutParams
zoomLayout.engine.setContainerSize(layoutParams.width, layoutParams.height, true)
Oder vielleicht so
zoomLayout.layoutParams = layoutParams
zoomLayout.post {
zoomLayout.engine.setContainerSize(layoutParams.width, layoutParams.height, true)
}
Wir könnten dies mit einer syncTransformation()-Funktion oder ähnlichem vereinfachen
@markusressel Okay, ich verstehe. Außerdem habe ich das Gefühl, dass ich nur 25% des Potenzials dieser Bibliothek nutzen möchte. Das Deaktivieren des Verwendungszwecks der Bibliothek ist eigentlich etwas dagegen und erwartet, dass es funktioniert. Alles was ich brauche ist Center-Crop mit Pan und Fling. Wenn Sie etwas vorzuschlagen haben, tun Sie es bitte. Vielen Dank.
Die Containergröße kann sich aus vielen Gründen ändern und wenn der Inhalt bereits gezoomt/geschwenkt wurde, denke ich, dass wir die Transformation nicht erneut anwenden sollten
@natario1 Wenn dies erwartet/erforderlich ist, sollte es ein Opt-in-Flag für dieses Verhalten geben. Für mich fühlt es sich wie eine Anti-Default-Erwartung an. Wenn Center-Crop angewendet wird und die Containergröße geändert wird, sollte Center-Crop beibehalten werden. Wenn wir jedoch keine Größenänderungen in ZoomLayout unterstützen, wäre dies nicht einmal wichtig.
Außerdem bin ich mit dem Bibliothekscode vom Dienstag beschäftigt. Ich weiß ~viel~ nichts darüber, wie Matrizen, Vektoren oder Shader funktionieren. Ich versuche zu lesen und zu modifizieren, um zu lernen. Aber ich habe Ihren Vorschlag bereits ausprobiert, bevor ich das Problem gemeldet habe. Als Ergebnis davon ist Pan sowohl für die horizontale als auch für die vertikale Richtung aktiviert. Außerdem ist das Zuschneiden in der Mitte nicht mehr verfügbar, da der Inhalt/das untergeordnete Element gezoomt zu sein scheint.
Danke für deine Hilfe. Es tut mir leid, dass ich viel länger gebraucht habe, um zu antworten.
@rupinderjeet Ich habe versucht, Ihr Beispiel zu reproduzieren, aber wenn ich das modifizierte LayoutParams
auf die Instanz ZoomLayout
anwende, erhalte ich unsere eigene Fehlermeldung:
java.lang.RuntimeException: ZoomLayout must be used with fixed dimensions (e.g. match_parent)
Verpasse ich etwas?
Hilfreichster Kommentar
Ich mag, wie es gerade funktioniert, die Containergröße kann sich aus vielen Gründen ändern, und wenn der Inhalt bereits gezoomt/geschwenkt wurde, sollten wir die Transformation meiner Meinung nach nicht erneut anwenden. Sie sollten in der Lage sein, das zu erreichen, was Sie möchten, wie folgt:
Oder vielleicht so
Wir könnten dies mit einer syncTransformation()-Funktion oder ähnlichem vereinfachen