Um die Ausführung der Übergangsanimation für gemeinsame Elemente anzupassen, Parameter, mit denen sich der Übergang von gemeinsam genutzten Elementen ändern lässt.
Animationsspezifikation
Um die Animationsspezifikationen für die Größe und Positionsbewegung zu ändern, können Sie
Einen anderen boundsTransform
-Parameter für Modifier.sharedElement()
angeben.
So erhalten Sie die Anfangs- und Zielposition von Rect
.
Um beispielsweise den Text im vorherigen Beispiel bogenförmig zu bewegen,
Bewegung den Parameter boundsTransform
, 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 Anpassen der Größe
Wenn Sie zwischen zwei gemeinsamen Grenzen animieren, können Sie den Parameter resizeMode
auf RemeasureToBounds
oder ScaleToBounds
festlegen. Dieser Parameter bestimmt, wie
wechselt das gemeinsame Element
zwischen den beiden Zuständen. ScaleToBounds
misst zuerst das untergeordnete Layout mit den Vorschau- (oder Ziel-)Einschränkungen. Anschließend wird das stabile Layout des untergeordneten Elements so skaliert, dass es in die gemeinsamen Grenzen passt.
ScaleToBounds
kann als „grafische Skala“ zwischen den Zuständen betrachtet werden.
Bei RemeasureToBounds
wird das untergeordnete Layout von sharedBounds
mit animierten festen Einschränkungen basierend auf der Zielgröße neu gemessen und neu angeordnet. Die Neumessung wird durch die Änderung der Begrenzungsgröße ausgelöst, was potenziell bei jedem Frame der Fall sein kann.
Für Text
-Kompositionen wird ScaleToBounds
empfohlen, da dadurch ein Neulayout und ein Neufluss von Text auf verschiedene Zeilen vermieden wird. Wenn die Grenzen unterschiedliche Seitenverhältnisse haben und Sie eine flüssige Kontinuität zwischen den beiden gemeinsamen Elementen wünschen, wird RemeasureToBounds
empfohlen.
Die Unterschiede zwischen den beiden Modi zum Ändern der Größe sind in den folgenden Beispielen zu sehen:
|
|
---|---|
Zum endgültigen Layout springen
Standardmäßig wird beim Übergang zwischen zwei Layouts die Layoutgröße zwischen dem Start- und dem Endstatus animiert. Dies kann unerwünschtes Verhalten sein, wenn zum Animieren von Inhalten wie Text.
Das folgende Beispiel zeigt den Beschreibungstext „Lorem Ipsum“ betreten
auf zwei unterschiedliche Arten. Im ersten Beispiel wird der Text
umgefaltet, während er
mit zunehmender Größe des Containers ein. Im zweiten Beispiel
Reflow anwenden, wenn er wächst. Durch Hinzufügen von Modifier.skipToLookaheadSize()
wird ein Reflow verhindert.
wenn er wächst.
Ohne Modifier.skipToLookahead() – beachten Sie, dass der Text „Lorem Ipsum“ neu formatiert wird |
Modifier.skipToLookahead(): Der Text „Lorem Ipsum“ behält seinen Endstatus zu Beginn der Animation bei. |
---|---|
Clips und Overlays
Ein wichtiges Konzept beim Erstellen gemeinsam genutzter Elemente in Compose ist, dass sie zwischen verschiedenen Compose-Elementen freigegeben werden können, wenn das Rendering des Compose-Elements in ein Ebenen-Overlay verschoben wird, wenn der Übergang zu seiner Übereinstimmung im Ziel gestartet wird. Das hat zur Folge, dass die Grenzen des übergeordneten Elements und seine Ebenentransformationen (z. B. Alpha und Skalierung) umgangen werden.
Es wird über anderen nicht freigegebenen UI-Elementen gerendert. Sobald die Umstellung abgeschlossen ist, wird das Element aus dem Overlay in sein eigenes DrawScope
verschoben.
Wenn Sie ein freigegebenes Element zu einer Form zuschneiden möchten, verwenden Sie die Standardfunktion Modifier.clip()
. 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 Sie sicherstellen müssen, dass ein gemeinsam genutztes Element nie außerhalb eines übergeordneten Elements gerendert wird
Container enthält, können Sie clipInOverlayDuringTransition
auf sharedElement()
festlegen. Standardmäßig verwendet clipInOverlayDuringTransition
für verschachtelte gemeinsame Begrenzungen den Clippfad des übergeordneten sharedBounds()
.
Wenn bestimmte UI-Elemente wie eine untere Leiste oder eine schwebende Aktionsschaltfläche während eines Übergangs von gemeinsamen Elementen immer oben bleiben sollen, verwenden Sie Modifier.renderInSharedTransitionScopeOverlay()
. Standardmäßig bleiben die Inhalte im Overlay, solange die gemeinsame Überblendung aktiv ist.
In Jetsnack muss das BottomAppBar
beispielsweise über dem gemeinsamen Element platziert werden, bis der Bildschirm nicht mehr sichtbar ist. Wenn Sie den Modifier zum Composeable hinzufügen, bleibt es hervorgehoben.
Ohne |
Mit |
---|---|
Vielleicht möchten Sie die nicht freigegebene zusammensetzbare Funktion
vor dem Übergang zu den anderen zusammensetzbaren Funktionen
übernehmen. Verwenden Sie in solchen Fällen renderInSharedTransitionScopeOverlay().animateEnterExit()
, um das Zusammenspiel der Elemente zu animieren, während die Überblendung des freigegebenen Elements ausgeführt wird:
JetsnackBottomBar( modifier = Modifier .renderInSharedTransitionScopeOverlay( zIndexInOverlay = 1f, ) .animateEnterExit( enter = fadeIn() + slideInVertically { it }, exit = fadeOut() + slideOutVertically { it } ) )
In dem seltenen Fall, dass Ihr gemeinsam genutztes Element nicht in einem
Overlay ist, kannst du renderInOverlayDuringTransition
auf sharedElement()
festlegen
auf false setzen.
Über Änderungen an der Größe gemeinsam genutzter Elemente benachrichtigen
Standardmäßig benachrichtigen sharedBounds()
und sharedElement()
die Eltern nicht
Container mit Größenänderungen, die sich beim Übergang des Layouts ändern.
Damit Größenänderungen beim Übergang an den übergeordneten Container weitergegeben werden,
Ändern Sie den Parameter placeHolderSize
in PlaceHolderSize.animatedSize
. Dadurch wird das Element vergrößert oder verkleinert. Alle anderen Elemente im Layout reagieren auf die Änderung.
|
Beachten Sie, dass sich die anderen Elemente in der Liste nach unten bewegen, wenn ein Element größer wird. |
---|---|