Aby dostosować sposób działania animacji wspólnych elementów, możesz użyć kilku parametrów do zmiany sposobu ich przenoszenia.
Specyfikacja animacji
Aby zmienić specyfikację animacji używaną przy przesuwaniu rozmiaru i pozycji, możesz podać inny parametr boundsTransform
w elemencie Modifier.sharedElement()
.
Podaje początkową pozycję Rect
i pozycję docelową Rect
.
Aby np. aby tekst z poprzedniego przykładu poruszał się po łuku, określ parametr boundsTransform
, by zastosować specyfikację 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żywamy 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, w jaki sposób wspólny element przechodzi między tymi dwoma stanami. ScaleToBounds
mierzy najpierw układ podrzędny z zastosowaniem ograniczeń „wyprzedzeniem” (lub „cel”). Następnie stabilny układ elementu podrzędnego jest skalowany, by dopasować go do wspólnych granic.
ScaleToBounds
to rodzaj „skali graficznej” między stanami.
Parametr RemeasureToBounds
ponownie mierzy i przekształca układ podrzędny elementu sharedBounds
z animowanymi ograniczeniami stałymi na podstawie rozmiaru docelowego. Ponowny pomiar jest wywoływany przez zmianę rozmiaru granic, która może dotyczyć każdej klatki.
W przypadku funkcji kompozycyjnych Text
zalecany jest format ScaleToBounds
, ponieważ pozwala to uniknąć przekazywania i przekładania tekstu na inne wiersze. W przypadku granic o różnych współczynnikach proporcji oraz jeśli chcesz zachować płynną ciągłość między 2 wspólnymi elementami, zalecamy użycie właściwości RemeasureToBounds
.
Różnice między tymi 2 trybami zmiany rozmiaru można zobaczyć w poniższych przykładach:
|
|
---|---|
Przejdź do ostatecznego układu
Domyślnie podczas przechodzenia między 2 układami rozmiar układu animuje się między stanem początkowym a końcowym. Może to być niepożądane zachowanie podczas animowania treści takich jak tekst.
W przykładzie poniżej widać, jak tekst opisu „Lorem Ipsum” pojawia się na ekranie na 2 różne sposoby. W pierwszym przykładzie tekst zmienia się w miarę zwiększania rozmiaru kontenera, a w drugim – jego układ nie zmienia się wraz ze wzrostem. Dodanie parametru Modifier.skipToLookaheadSize()
zapobiega przeformatowaniu w miarę jego wzrostu.
Brak parametru Modifier.skipToLookahead() – zwróć uwagę na zmianę układu tekstu „Lorem Ipsum”. |
Modifier.skipToLookahead() – zwróć uwagę, że tekst „Lorem Ipsum” zachowuje swój końcowy stan na początku animacji. |
---|---|
Klip i nakładki
Ważnym aspektem podczas tworzenia wspólnych elementów w funkcji Utwórz jest to, że aby mogły one współdzielić różne elementy kompozycyjne, renderowanie elementu kompozycyjnego jest podnoszone do nakładki warstwy, gdy przejście zaczyna się do niej pasować w miejscu docelowym. Skutkiem jest to, że poza granicami jednostki nadrzędnej i przekształceniami jej warstwy (np. alfa i skalę).
Będzie się wyświetlać nad innymi nieudostępnionymi elementami interfejsu, a po zakończeniu przejścia element zostanie usunięty z nakładki do własnego elementu DrawScope
.
Aby przyciąć udostępniony element do kształtu, użyj standardowej funkcji Modifier.clip()
. Umieść go po kolumnie 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ępniany element nigdy nie będzie renderowany poza kontenerem nadrzędnym, możesz ustawić clipInOverlayDuringTransition
w polu sharedElement()
. Domyślnie w przypadku zagnieżdżonych wspólnych granic clipInOverlayDuringTransition
używa ścieżki klipu z elementu nadrzędnego sharedBounds()
.
Aby ułatwić pozostawianie określonych elementów interfejsu, takich jak dolny pasek czy pływający przycisk polecenia, zawsze na górze podczas przejścia elementu współdzielonego, użyj właściwości Modifier.renderInSharedTransitionScopeOverlay()
. Domyślnie ten modyfikator zachowuje treść nakładek w czasie, gdy udostępnione przejście jest aktywne.
Na przykład w Jtsnacku trzeba umieszczać BottomAppBar
nad udostępnionym elementem, aż do momentu, gdy ekran przestanie być widoczny. Dodanie modyfikatora do funkcji kompozycyjnej
sprawia, że zostanie on podniesiony.
Bez: |
Przez: |
---|---|
Czasami możesz chcieć, aby nieudostępniany element kompozycyjny był animowany i pozostał nad innymi elementami kompozycyjnymi przed przeniesieniem. W takich przypadkach użyj funkcji renderInSharedTransitionScopeOverlay().animateEnterExit()
, aby animować obiekt kompozycyjny w trakcie przenoszenia elementów wspólnych:
JetsnackBottomBar( modifier = Modifier .renderInSharedTransitionScopeOverlay( zIndexInOverlay = 1f, ) .animateEnterExit( enter = fadeIn() + slideInVertically { it }, exit = fadeOut() + slideOutVertically { it } ) )
W rzadkich przypadkach, gdy nie chcesz, by udostępniony element był renderowany w nakładce, możesz ustawić właściwość renderInOverlayDuringTransition
w polu sharedElement()
na wartość fałsz.
Powiadamianie układów równorzędnych o zmianach rozmiaru udostępnianego elementu
Domyślnie sharedBounds()
i sharedElement()
nie powiadamiają kontenera nadrzędnego o zmianie rozmiaru podczas przenoszenia układu.
Aby przekazywać zmiany rozmiaru w kontenerze nadrzędnym podczas jego przenoszenia, zmień parametr placeHolderSize
na PlaceHolderSize.animatedSize
. W ten sposób element powiększy się lub zmniejsz. Pozostałe elementy układu
reagują na tę zmianę.
|
(Zwróć uwagę, jak inne elementy na liście przesuwają się w dół w odpowiedzi na rosnący element). |
---|---|