Per personalizzare la modalità di esecuzione dell'animazione di transizione degli elementi condivisi, sono disponibili parametri che possono essere utilizzati per cambiare la modalità di transizione degli elementi condivisi.
Specifiche animazione
Per modificare le specifiche di animazione utilizzate per il movimento delle dimensioni e della posizione, puoi specificare un parametro boundsTransform
diverso su Modifier.sharedElement()
.
In questo modo vengono fornite la posizione iniziale Rect
e la posizione target Rect
.
Ad esempio, per fare in modo che il testo dell'esempio precedente si sposti con un arco
specifica il movimento, 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
parametriModalità di ridimensionamento
Quando crei animazioni tra due limiti condivisi, puoi impostare il parametro resizeMode
a RemeasureToBounds
o ScaleToBounds
. Questo parametro determina il modo in cui
le transizioni degli elementi condivisi tra i due stati. ScaleToBounds
prima
misura il layout secondario con i vincoli lookahead (o target). Poi, il layout stabile del componente secondario viene ridimensionato in modo da adattarsi ai limiti condivisi.
ScaleToBounds
può essere considerato una "scala grafica" tra gli stati.
Mentre RemeasureToBounds
esegue una nuova misurazione e un nuovo layout del layout secondario di
sharedBounds
con vincoli fissi animati basati sulle dimensioni target. La
nuova misurazione viene attivata dalla modifica della dimensione dei limiti, che potrebbe potenzialmente
per ogni frame.
Per gli elementi componibili Text
è consigliato ScaleToBounds
per evitare il relayout
e ripetere il flusso del testo su righe diverse. Per i limiti con proporzioni diverse e se vuoi una continuità fluida tra i due elementi condivisi, è consigliato 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 vengono animate tra lo stato iniziale e quello finale. Questo potrebbe essere un comportamento indesiderato quando si animano contenuti come il testo.
L'esempio seguente mostra il testo descrittivo "Lorem Ipsum" visualizzato sullo schermo in due modi diversi. Nel primo esempio, il testo si ripete durante il processo
inserisce all'aumentare delle dimensioni del contenitore, nel secondo esempio il testo non
l'adattamento dinamico del contenuto
man mano che cresce. L'aggiunta di Modifier.skipToLookaheadSize()
impedisce il riflusso man mano che cresce.
Nessun Modifier.skipToLookahead() - notare il "Lorem Ipsum" ripetizione flusso del testo |
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, nell'ordine da condividere tra diversi componibili, il rendering del l'elemento componibile viene elevato in un overlay di livello quando la transizione viene avviata la sua corrispondenza nella destinazione. Il risultato è che uscirà dai limiti del livello principale e dalle relative trasformazioni (ad esempio alpha e scala).
Verrà visualizzata sopra gli altri elementi UI non condivisi, una volta completata la transizione
completato, l'elemento verrà eliminato dall'overlay al suo DrawScope
.
Per ritagliare un elemento condiviso in una forma, utilizza lo standard Modifier.clip()
personalizzata. 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 elemento principale
container, puoi impostare clipInOverlayDuringTransition
su sharedElement()
. Di
predefinita, per i limiti condivisi nidificati, clipInOverlayDuringTransition
utilizza il clip
percorso dal sharedBounds()
principale.
Per mantenere sempre in primo piano elementi dell'interfaccia utente specifici, come una barra in basso o un pulsante di azione flottante, durante la transizione di un elemento condiviso, utilizza Modifier.renderInSharedTransitionScopeOverlay()
. Per impostazione predefinita, questo modificatore mantiene i contenuti nell'overlay durante il periodo di attivazione della transizione condivisa.
Ad esempio, in Jetsnack, BottomAppBar
deve essere posizionato sopra
l'elemento condiviso finché lo schermo non diventa visibile. L'aggiunta del modificatore al composable lo mantiene in primo piano.
Senza |
Con |
---|---|
A volte potresti voler animare il composable non condiviso e rimanere sopra gli altri composable prima della transizione. In questi casi, utilizza
renderInSharedTransitionScopeOverlay().animateEnterExit()
per animare il
composabile in uscita durante l'esecuzione della transizione dell'elemento condiviso:
JetsnackBottomBar( modifier = Modifier .renderInSharedTransitionScopeOverlay( zIndexInOverlay = 1f, ) .animateEnterExit( enter = fadeIn() + slideInVertically { it }, exit = fadeOut() + slideOutVertically { it } ) )
Nei rari casi in cui non vuoi che l'elemento condiviso 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 informano il contenitore principale di eventuali modifiche alle 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 aumenta o diminuisce di dimensioni. Tutti gli altri elementi nel layout rispondono a
la modifica.
|
(notare come gli altri elementi dell'elenco si spostano verso il basso in risposta all'aumento di un elemento) |
---|---|