Um die Ausführung der Übergangsanimation mit gemeinsam genutzten Elementen anzupassen, gibt es einige Parameter, mit denen sich der Übergang der gemeinsam genutzten Elemente ändern lässt.
Animationsspezifikation
Wenn Sie die für die Größe und Positionsbewegung verwendete Animationsspezifikation ändern möchten, können Sie für Modifier.sharedElement()
einen anderen boundsTransform
-Parameter angeben.
Dadurch werden die Ausgangsposition Rect
und die Zielposition Rect
angegeben.
Wenn der Text im vorherigen Beispiel beispielsweise mit einer Bogenbewegung bewegt werden soll, geben Sie den Parameter boundsTransform
an, um eine keyframes
-Spezifikation zu verwenden:
val textBoundsTransform = BoundsTransform { initialBounds, targetBounds -> keyframes { durationMillis = boundsAnimationDurationMillis initialBounds at 0 using ArcMode.ArcBelow using FastOutSlowInEasing targetBounds at boundsAnimationDurationMillis } } Text( "Cupcake", fontSize = 28.sp, modifier = Modifier.sharedBounds( rememberSharedContentState(key = "title"), animatedVisibilityScope = animatedVisibilityScope, boundsTransform = textBoundsTransform ) )
Sie können eine beliebige AnimationSpec
verwenden. In diesem Beispiel wird eine keyframes
-Spezifikation verwendet.
boundsTransform
-ParameterModus zum Ändern der Größe
Wenn Sie zwischen zwei gemeinsamen Grenzen animieren, können Sie den Parameter resizeMode
auf RemeasureToBounds
oder ScaleToBounds
setzen. Dieser Parameter bestimmt, wie das gemeinsame Element zwischen den beiden Zuständen wechselt. ScaleToBounds
misst zuerst das untergeordnete Layout mit den Lookahead-Einschränkungen (oder Zieleinschränkungen). Dann wird das stabile Layout des untergeordneten Elements so skaliert, dass es in die gemeinsamen Grenzen passt.
ScaleToBounds
kann als eine "grafische Skala" zwischen den Zuständen betrachtet werden.
Während RemeasureToBounds
das untergeordnete Layout von sharedBounds
mit animierten festen Einschränkungen basierend auf der Zielgröße noch einmal misst und neu erstellt. Die erneute Messung wird durch die Änderung der Begrenzungsgröße ausgelöst, die möglicherweise jeden Frame umfassen kann.
Für zusammensetzbare Text
-Elemente wird ScaleToBounds
empfohlen, da damit das Layout und der Umfluss von Text in verschiedene Zeilen vermieden werden. Für Grenzen mit unterschiedlichen Seitenverhältnissen und für eine flüssige Kontinuität zwischen den beiden gemeinsamen Elementen wird RemeasureToBounds
empfohlen.
In den folgenden Beispielen sehen Sie den Unterschied zwischen den beiden Modi zur Größenanpassung:
|
|
---|---|
Zum endgültigen Layout springen
Beim Übergang zwischen zwei Layouts wird die Layoutgröße zwischen dem Start- und dem Endzustand standardmäßig animiert. Bei der Animation von Inhalten wie Text kann dies unerwünschtes Verhalten sein.
Das folgende Beispiel zeigt, wie der Beschreibungstext „Lorem Ipsum“ auf zwei verschiedene Arten in den Bildschirm gelangt. Im ersten Beispiel wird der Text umgebrochen, wenn er größer wird, wenn der Container größer wird. Im zweiten Beispiel wird der Text nicht automatisch angepasst, wenn er größer wird. Wenn Sie Modifier.skipToLookaheadSize()
hinzufügen, wird ein dynamischer Umbruch verhindert, während er größer wird.
Kein Modifier.skipToLookahead() - sehen Sie, dass der Text "Lorem Ipsum" umfließt. |
Modifier.skipToLookahead(): Beachten Sie, dass der Text "Lorem Ipsum" zu Beginn der Animation seinen endgültigen Zustand beibehält. |
---|---|
Clips und Overlays
Ein wichtiges Konzept beim Erstellen gemeinsam genutzter Elemente in Compose besteht darin, dass für die gemeinsame Nutzung durch verschiedene zusammensetzbare Funktionen das Rendering der zusammensetzbaren Funktion zu einem Ebenen-Overlay erhöht wird, wenn der Übergang zu dessen Übereinstimmung im Ziel beginnt. Dadurch werden die Grenzen des übergeordneten Elements und seine Ebenentransformationen (z. B. Alpha und Skalierung) maskiert.
Es wird über anderen nicht geteilten UI-Elementen gerendert. Nach Abschluss des Übergangs wird das Element vom Overlay in sein eigenes DrawScope
-Element verschoben.
Verwenden Sie die Standardfunktion Modifier.clip()
, um ein gemeinsam genutztes Element auf eine Form zu kürzen. Platziere ihn nach sharedElement()
:
Image( painter = painterResource(id = R.drawable.cupcake), contentDescription = "Cupcake", modifier = Modifier .size(100.dp) .sharedElement( rememberSharedContentState(key = "image"), animatedVisibilityScope = this@AnimatedContent ) .clip(RoundedCornerShape(16.dp)), contentScale = ContentScale.Crop )
Wenn ein gemeinsam genutztes Element nie außerhalb eines übergeordneten Containers gerendert werden soll, können Sie clipInOverlayDuringTransition
auf sharedElement()
festlegen. Bei verschachtelten freigegebenen Grenzen verwendet clipInOverlayDuringTransition
standardmäßig den Clippfad des übergeordneten sharedBounds()
.
Wenn Sie möchten, dass bestimmte UI-Elemente wie eine Leiste am unteren Rand oder eine unverankerte Aktionsschaltfläche während eines Übergangs mit gemeinsam genutzten Elementen immer oben bleiben, verwenden Sie Modifier.renderInSharedTransitionScopeOverlay()
. Dieser Modifikator behält standardmäßig den Inhalt im Overlay bei, während der gemeinsame Übergang aktiv ist.
In Jetsnack muss BottomAppBar
beispielsweise so lange auf dem gemeinsam genutzten Element platziert werden, bis der Bildschirm nicht mehr sichtbar ist. Durch Hinzufügen des Modifizierers
zur zusammensetzbaren Funktion bleibt dieser erhöht.
Ohne |
Mit |
---|---|
Manchmal möchten Sie vielleicht, dass die nicht freigegebene zusammensetzbare Funktion weg animiert wird und vor dem Übergang über die anderen zusammensetzbaren Funktionen gelegt wird. Verwenden Sie in diesen Fällen renderInSharedTransitionScopeOverlay().animateEnterExit()
, um die zusammensetzbare Funktion zu animieren, während der Übergang mit gemeinsam genutzten Elementen ausgeführt wird:
JetsnackBottomBar( modifier = Modifier .renderInSharedTransitionScopeOverlay( zIndexInOverlay = 1f, ) .animateEnterExit( enter = fadeIn() + slideInVertically { it }, exit = fadeOut() + slideOutVertically { it } ) )
Falls Sie nicht möchten, dass ein geteiltes Element in einem Overlay gerendert wird, können Sie renderInOverlayDuringTransition
auf sharedElement()
auf „false“ setzen.
gleichgeordnete Layouts über Änderungen an gemeinsam genutzter Elementgröße benachrichtigen
Standardmäßig benachrichtigen sharedBounds()
und sharedElement()
den übergeordneten Container nicht über Größenänderungen bei Layoutübergängen.
Damit Größenänderungen beim Übergang an den übergeordneten Container weitergegeben werden, ändern Sie den Parameter placeHolderSize
in PlaceHolderSize.animatedSize
. Dadurch vergrößert oder verkleinert sich das Element. Alle anderen Elemente im Layout
reagieren auf die Änderung.
|
Beachten Sie, wie die anderen Elemente in der Liste als Reaktion auf das wachsende Element nach unten verschoben werden. |
---|---|