Aby dostosować sposób wyświetlania udostępnianej animacji przejścia elementu, parametrów, które pozwalają zmienić sposób przejścia udostępnianych elementów.
Specyfikacja animacji
Aby zmienić specyfikację animacji służącą do określania rozmiaru i pozycji obrazu, możesz użyć opcji
określić inny parametr boundsTransform
w elemencie Modifier.sharedElement()
.
W ten sposób określasz początkową pozycję Rect
i docelową pozycję Rect
.
Aby na przykład tekst z poprzedniego przykładu przesuwał się wraz z łukiem
motion, określ parametr boundsTransform
, by użyć specyfikacji keyframes
:
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 ) )
Możesz użyć dowolnego elementu AnimationSpec
. W tym przykładzie użyto specyfikacji keyframes
.
Tryb zmiany rozmiaru
Podczas animowania między 2 wspólnymi granicami możesz ustawić parametr resizeMode
na RemeasureToBounds
lub ScaleToBounds
. Ten parametr określa sposób
czyli przejścia między tymi dwoma stanami. Pierwsze ScaleToBounds
mierzy układ podrzędny z ograniczeniami (lub elementami docelowymi) z wyprzedzeniem. Później
stabilny układ dziecka jest skalowany tak, aby pasował do wspólnych granic.
Element ScaleToBounds
można określić jako „skalę graficzną” między stanami.
Z kolei RemeasureToBounds
ponownie mierzy i przekazuje układ podrzędny
sharedBounds
z animowanymi stałymi ograniczeniami na podstawie rozmiaru docelowego. Ponowne pomiary są wywoływane przez zmianę rozmiaru granic, która może potencjalnie wystąpić w każdej klatce.
W przypadku Text
komponentów kompozycyjnych zalecamy użycie ScaleToBounds
, ponieważ pozwala to uniknąć przekazywania
i układanie tekstu w różne wiersze. Jeśli chcesz uzyskać płynne przejście między 2 elementami, których współczynniki proporcji są różne, zalecamy użycie RemeasureToBounds
.
Różnica między tymi dwoma trybami widać w przykładach poniżej:
|
|
---|---|
Przejdź do ostatecznego układu
Domyślnie przy przechodzeniu między 2 układami rozmiar układu jest animowany. między stanem początkowym i końcowym. Może to być niepożądane, gdy animowanie treści, np. tekstu.
Poniższy przykład ilustruje tekst opisu „Lorem Ipsum” Wprowadzanie
na dwa różne sposoby. W pierwszym przykładzie tekst jest przeformatowywany, gdy wchodzi do kontenera, który zwiększa swój rozmiar, a w drugim przykładzie tekst nie jest przeformatowywany, gdy rośnie. Dodanie tych elementów (Modifier.skipToLookaheadSize()
) uniemożliwi przeformatowanie
w miarę wzrostu.
No Modifier.skipToLookahead() – zwróć uwagę na funkcję „Lorem Ipsum” zmiana przepływu tekstu |
Modifier.skipToLookahead() – zwróć uwagę na funkcję „Lorem Ipsum” tekst zachowuje końcowy stan na początku animacji |
---|---|
Klip i nakładki
Podczas tworzenia elementów współdzielonych w komponencie należy pamiętać, że aby można było je udostępniać między różnymi komponentami, renderowanie komponentu jest podnoszone do nakładki warstwy, gdy rozpoczyna się przejście do jego odpowiednika na stronie docelowej. W efekcie wykracza poza granice obiektu nadrzędnego i jego przekształceń warstwy (np. alfa i skali).
Element będzie renderowany na wierzchu innych elementów interfejsu, które nie są współdzielone. Gdy przejście się zakończy, element zostanie usunięty z nakładki i przeniesiony do własnej DrawScope
.
Aby przyciąć udostępniony element do kształtu, użyj standardowego Modifier.clip()
. Umieść go za elementem 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 )
Jeśli chcesz mieć pewność, że udostępniony element nigdy nie będzie renderowany poza nadrzędnym kontenerem, możesz ustawić clipInOverlayDuringTransition
w sharedElement()
. Domyślnie w przypadku zagnieżdżonych wspólnych zakresów clipInOverlayDuringTransition
używa ścieżki klipu z folderu nadrzędnego sharedBounds()
.
Aby zapewnić, że określone elementy interfejsu, np. dolna belka lub pływający przycisk, będą zawsze widoczne u góry podczas przejścia do elementu współdzielonego, użyj atrybutu Modifier.renderInSharedTransitionScopeOverlay()
. Domyślnie ta wartość
powoduje, że treść jest wyświetlana na nakładce w czasie, gdy jest udostępniana
przejście jest aktywne.
Na przykład w Jetsnack obiekt BottomAppBar
musi znaleźć się na elemencie
do momentu, gdy ekran stanie się niewidoczny. Dodawanie modyfikatora
kompozycyjne, pozostaje w górę.
Bez: |
Przez: |
---|---|
Czasami możesz chcieć, aby Twoja nieudostępniona funkcja kompozycyjna była animowana
pozostaje nad innymi kompozycjami przed przejściem. W takich przypadkach użyj wartości
renderInSharedTransitionScopeOverlay().animateEnterExit()
, aby animować
composable out podczas przejścia wspólnego elementu:
JetsnackBottomBar( modifier = Modifier .renderInSharedTransitionScopeOverlay( zIndexInOverlay = 1f, ) .animateEnterExit( enter = fadeIn() + slideInVertically { it }, exit = fadeOut() + slideOutVertically { it } ) )
W rzadkich przypadkach, gdy nie chcesz, by udostępniany element był renderowany w
można ustawić renderInOverlayDuringTransition
na sharedElement()
na fałsz.
Powiadamianie układów równorzędnych o zmianach rozmiaru udostępnianych elementów
Domyślnie sharedBounds()
i sharedElement()
nie powiadamiają rodziców
kontener o dowolnym rozmiarze zmienia się wraz z przejściem układu.
Aby rozpowszechnić zmiany rozmiaru w kontenerze nadrzędnym podczas przejścia, zmień parametr placeHolderSize
na PlaceHolderSize.animatedSize
. Wykonuję
powoduje więc powiększanie lub pomniejszanie elementu. Wszystkie inne elementy układu reagują na tę zmianę.
|
(Zwróć uwagę, jak pozostałe elementy na liście przesuwają się w dół w odpowiedzi na rosnącą pozycję jednego elementu). |
---|---|