Aby dostosować sposób działania animacji przejścia elementu współdzielonego, możesz użyć kilku parametrów, które pozwolą zmienić sposób przejścia elementów współdzielonych.
Specyfikacja animacji
Aby zmienić specyfikację animacji używaną do przesuwania rozmiaru i pozycji, możesz określić inny parametr boundsTransform
w pliku Modifier.sharedElement()
.
Podaje to początkową pozycję Rect
i docelową pozycję Rect
.
Aby na przykład tekst z poprzedniego przykładu poruszał się po łuku, użyj parametru boundsTransform
, aby 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 AnimationSpec
. W tym przykładzie użyto specyfikacji keyframes
.
boundsTransform
parametryTryb zmiany rozmiaru
Podczas animowania między 2 wspólnymi granicami możesz ustawić parametr resizeMode
na RemeasureToBounds
lub ScaleToBounds
. Ten parametr określa, jak element współdzielony przechodzi między dwoma stanami. ScaleToBounds
first mierzy układ podrzędny z wyprzedzeniem (lub z ograniczeniami docelowymi). Następnie stabilny układ elementu podrzędnego jest skalowany tak, aby zmieścił się w udostępnionych granicach.
ScaleToBounds
można traktować jako „skalę graficzną” między stanami.
Natomiast RemeasureToBounds
ponownie mierzy i układa układ podrzędny sharedBounds
z animowanymi stałymi ograniczeniami na podstawie rozmiaru docelowego. Ponowny pomiar jest wywoływany przez zmianę rozmiaru ramki, która może następować w każdej klatce.
W przypadku komponentów kompozycyjnych Text
zalecamy używanie ScaleToBounds
, ponieważ pozwala to uniknąć ponownego układania i przelewania tekstu do innych wierszy. RemeasureToBounds
jest zalecane w przypadku granic o różnych współczynnikach proporcji oraz jeśli chcesz uzyskać płynną ciągłość między 2 wspólnymi elementami.
Różnicę między tymi 2 trybami zmiany rozmiaru widać w przykładach poniżej:
|
|
---|---|
Przejdź do układu końcowego
Domyślnie podczas przechodzenia między dwoma układami rozmiar układu jest animowany między stanem początkowym a końcowym. Może to być niepożądane zachowanie podczas animowania treści, takich jak tekst.
Poniższy przykład pokazuje tekst opisu „Lorem Ipsum” pojawiający się na ekranie na 2 różne sposoby. W pierwszym przykładzie tekst jest ponownie formatowany w miarę pojawiania się w kontenerze, który zwiększa swój rozmiar. W drugim przykładzie tekst nie dopasowuje się do rozmiaru, gdy się powiększa. Dodanie Modifier.skipToLookaheadSize()
zapobiega ponownemu przepływowi treści podczas powiększania.
Brak |
|
---|---|
Klipy i nakładki
Aby udostępniać elementy między różnymi funkcjami kompozycyjnymi, renderowanie funkcji kompozycyjnej jest przenoszone do nakładki warstwy, gdy rozpoczyna się przejście do pasującego elementu w miejscu docelowym. W efekcie element wyjdzie poza granice elementu nadrzędnego i jego przekształcenia warstwy (np. przezroczystość i skalę).
Będzie się wyświetlać nad innymi nieudostępnionymi elementami interfejsu. Po zakończeniu przejścia element zostanie przeniesiony z nakładki do własnej DrawScope
.
Aby przyciąć udostępniony element do kształtu, użyj standardowej funkcji Modifier.clip()
. Umieść go po znaku 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 kontenerem nadrzędnym, możesz ustawić clipInOverlayDuringTransition
na sharedElement()
. Domyślnie w przypadku zagnieżdżonych udostępnionych granic funkcja clipInOverlayDuringTransition
używa ścieżki przycinania z nadrzędnego elementu sharedBounds()
.
Aby podczas przejścia elementu udostępnionego zachować na wierzchu określone elementy interfejsu, takie jak pasek u dołu lub pływający przycisk działania, użyj Modifier.renderInSharedTransitionScopeOverlay()
. Domyślnie ten modyfikator utrzymuje treść w nakładce w czasie, gdy aktywna jest udostępniona animacja.
Na przykład w aplikacji Jetsnack element BottomAppBar
musi być umieszczony na elemencie współdzielonym, dopóki ekran nie będzie widoczny. Dodanie modyfikatora do funkcji kompozycyjnej sprawia, że pozostaje ona na wyższym poziomie.
Bez: |
Przez: |
---|---|
Możesz chcieć, aby element kompozycyjny, który nie jest współdzielony, również znikał z animacją i pozostawał na wierzchu innych elementów kompozycyjnych przed przejściem. W takich przypadkach użyj funkcji renderInSharedTransitionScopeOverlay().animateEnterExit()
, aby animować element kompozycyjny podczas przejścia elementu udostępnionego:
JetsnackBottomBar( modifier = Modifier .renderInSharedTransitionScopeOverlay( zIndexInOverlay = 1f, ) .animateEnterExit( enter = fadeIn() + slideInVertically { it }, exit = fadeOut() + slideOutVertically { it } ) )
W rzadkich przypadkach, gdy chcesz, aby udostępniony element nie był renderowany w nakładce, możesz ustawić wartość renderInOverlayDuringTransition
w sharedElement()
na false.
Powiadamianie układów równorzędnych o zmianach rozmiaru elementu udostępnionego
Domyślnie elementy sharedBounds()
i sharedElement()
nie powiadamiają kontenera nadrzędnego o żadnych zmianach rozmiaru podczas przejść układu.
Aby zmiany rozmiaru były propagowane do kontenera nadrzędnego podczas przejścia, zmień parametr placeHolderSize
na PlaceHolderSize.animatedSize
. W ten sposób możesz powiększyć lub pomniejszyć element. Wszystkie pozostałe elementy układu reagują na zmianę.
|
(Zwróć uwagę, jak pozostałe elementy listy przesuwają się w dół, gdy jeden z nich się powiększa). |
---|---|