Per personalizzare la modalità di esecuzione dell'animazione di transizione degli elementi condivisi, sono disponibili alcuni parametri che possono essere utilizzati per modificare la transizione degli elementi condivisi.
Specifiche animazione
Per modificare la specifica dell'animazione utilizzata per il movimento di dimensioni e posizione, puoi specificare un parametro boundsTransform
diverso su Modifier.sharedElement()
.
Fornisce la posizione iniziale di Rect
e la posizione Rect
target.
Ad esempio, per fare in modo che il testo nell'esempio precedente si sposti con un movimento arco, specifica il parametro boundsTransform
per utilizzare una specifica 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 ) )
Puoi utilizzare qualsiasi AnimationSpec
. Questo esempio utilizza una specifica keyframes
.
boundsTransform
Modalità di ridimensionamento
Quando crei animazioni tra due limiti condivisi, puoi impostare il parametro resizeMode
su RemeasureToBounds
o ScaleToBounds
. Questo parametro determina il modo in cui
l'elemento condiviso passa tra i due stati. ScaleToBounds
misura innanzitutto il layout secondario con i vincoli lookahead (o target). A questo punto, il layout stabile del file secondario viene ridimensionato per adattarsi ai limiti condivisi.
ScaleToBounds
può essere considerato una "scala grafica" tra gli stati.
RemeasureToBounds
rimisura e modifica il layout del layout secondario di
sharedBounds
con vincoli fissi animati in base alle dimensioni target. La nuova misurazione viene attivata dalla modifica delle dimensioni dei limiti, che potrebbe riguardare ogni frame.
Per gli elementi componibili Text
è consigliato ScaleToBounds
perché eviterà il relayout e l'adattamento dinamico del contenuto del testo su righe diverse. Per limiti con proporzioni diverse e se desideri una continuità fluida tra i due elementi condivisi, si consiglia RemeasureToBounds
.
La differenza tra le due modalità di ridimensionamento si può vedere negli esempi che seguono:
|
|
---|---|
Vai al layout finale
Per impostazione predefinita, durante la transizione tra due layout, le dimensioni del layout si animano tra lo stato iniziale e quello finale. Questo potrebbe essere un comportamento indesiderato quando si aggiungono contenuti animati come testo.
L'esempio seguente illustra il testo della descrizione "Lorem Ipsum" che entra
nella schermata in due modi diversi. Nel primo esempio il testo si adatta automaticamente man mano che entra
a mano a mano che il contenitore aumenta le dimensioni, nel secondo il testo non si adatta
in base alle dimensioni del contenitore. L'aggiunta di Modifier.skipToLookaheadSize()
impedisce la ripetizione
del flusso man mano che cresce.
No Modifier.skipToLookahead(): nota che il testo "Lorem Ipsum" si ripete |
Modifier.skipToLookahead(): nota che il testo "Lorem Ipsum" mantiene il suo stato finale all'inizio dell'animazione. |
---|---|
Clip e overlay
Un concetto importante durante la creazione di elementi condivisi in Compose è che, per consentire la condivisione tra diversi elementi componibili, il rendering dell'elemento componibile viene elevato in un overlay di livelli quando la transizione inizia e corrisponde alla destinazione. L'effetto è che esce dai limiti del livello padre e dalle trasformazioni dei livelli (ad esempio alfa e scala).
Verrà visualizzato sopra altri elementi UI non condivisi. Al termine della transizione, l'elemento verrà eliminato dall'overlay al proprio DrawScope
.
Per ritagliare un elemento condiviso in una forma, utilizza la funzione Modifier.clip()
standard. Posizionalo dopo il 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 )
Se devi assicurarti che un elemento condiviso non venga mai visualizzato all'esterno di un contenitore
principale, puoi impostare clipInOverlayDuringTransition
su sharedElement()
. Per impostazione predefinita, per i limiti condivisi nidificati, clipInOverlayDuringTransition
utilizza il percorso di clip dall'elemento principale sharedBounds()
.
Per mantenere sempre in alto elementi specifici dell'interfaccia utente, ad esempio una barra inferiore o un pulsante di azione mobile, durante la transizione di un elemento condiviso, utilizza
Modifier.renderInSharedTransitionScopeOverlay()
. Per impostazione predefinita, questo
modificatore conserva i contenuti dell'overlay durante il periodo in cui è attiva la transizione
condivisa.
Ad esempio, in Jetsnack, BottomAppBar
deve essere posizionato sopra l'elemento condiviso fino a quando lo schermo non sarà visibile. L'aggiunta del modificatore
al componibile mantiene elevato il suo valore.
Senza |
Con |
---|---|
A volte potresti volere che il componibile non condiviso si anima e che
resti sopra gli altri componibili prima della transizione. In questi casi, utilizza renderInSharedTransitionScopeOverlay().animateEnterExit()
per animare l'elemento componibile durante l'esecuzione della transizione dell'elemento condiviso:
JetsnackBottomBar( modifier = Modifier .renderInSharedTransitionScopeOverlay( zIndexInOverlay = 1f, ) .animateEnterExit( enter = fadeIn() + slideInVertically { it }, exit = fadeOut() + slideOutVertically { it } ) )
Nel raro caso in cui desideri che l'elemento condiviso non venga visualizzato in un overlay, puoi impostare renderInOverlayDuringTransition
su sharedElement()
su false.
Invia una notifica ai layout di pari livello delle modifiche alle dimensioni degli elementi condivisi
Per impostazione predefinita, sharedBounds()
e sharedElement()
non inviano al contenitore principale notifiche relative a modifiche delle dimensioni durante le transizioni del layout.
Per propagare le modifiche delle dimensioni al contenitore principale durante la transizione,
modifica il parametro placeHolderSize
in PlaceHolderSize.animatedSize
. In questo modo l'elemento si espande o si riduce. Tutti gli altri elementi nel layout
rispondono al cambiamento.
|
(Osserva come le altre voci nell'elenco si spostano verso il basso in risposta all'aumento di una voce) |
---|---|