Para personalizar la forma en que se ejecuta la animación de transición de elementos compartidos, hay algunos parámetros que se pueden usar para cambiar la forma en que se transfieren los elementos compartidos.
Especificaciones de animación
Para cambiar las especificaciones de la animación utilizadas para el tamaño y el movimiento de posición, puedes
especifica un parámetro boundsTransform
diferente en Modifier.sharedElement()
.
Esto proporciona la posición inicial de Rect
y la posición de destino de Rect
.
Por ejemplo, para hacer que el texto del ejemplo anterior se mueva con un arco
movimiento, especifica el parámetro boundsTransform
para usar una especificación de 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 ) )
Puedes usar cualquier AnimationSpec
. En este ejemplo, se usa una especificación keyframes
.
Modo de cambio de tamaño
Cuando realizas animaciones entre dos límites compartidos, puedes establecer el parámetro resizeMode
a RemeasureToBounds
o ScaleToBounds
. Este parámetro determina cómo
el elemento compartido realiza una transición entre los dos estados. ScaleToBounds
primero mide el diseño secundario con las restricciones de visualización anticipada (o objetivo). Luego, el diseño estable del elemento secundario se ajusta para que se ajuste a los límites compartidos.
Se puede considerar ScaleToBounds
como una "escala gráfica" entre los estados.
Mientras que RemeasureToBounds
vuelve a medir y a diseñar el diseño secundario de sharedBounds
con restricciones fijas animadas según el tamaño objetivo. La re-medición se activa por el cambio de tamaño de los límites, que podría ser cada fotograma.
Para los elementos componibles Text
, se recomienda usar ScaleToBounds
, ya que evitará el rediseño.
y reprocesamiento del texto en diferentes líneas. Para límites que tienen diferentes relaciones de aspecto y si deseas una continuidad fluida entre los dos elementos compartidos, se recomienda RemeasureToBounds
.
La diferencia entre los dos modos de cambio de tamaño se puede ver en los siguientes ejemplos:
|
|
---|---|
Ir al diseño final
De forma predeterminada, al hacer la transición entre dos diseños, se anima el tamaño del diseño. entre su estado inicial y final. Este puede ser un comportamiento no deseado cuando se anima contenido, como texto.
En el siguiente ejemplo, se ilustra el texto de descripción "Lorem Ipsum" que ingresa a la pantalla de dos maneras diferentes. En el primer ejemplo, el texto se reprocesa a medida que
ingresa a medida que el tamaño del contenedor aumenta; en el segundo ejemplo, el texto no
se reprocesa a medida que crece. Agregar Modifier.skipToLookaheadSize()
evita el reprocesamiento
a medida que crece.
No hay Modifier.skipToLookahead(). Observa el "Lorem Ipsum". reprocesamiento de texto |
Modifier.skipToLookahead(): Observa que el texto "Lorem Ipsum" mantiene su estado final al comienzo de la animación. |
---|---|
Recortar y superposiciones
Un concepto importante a la hora de crear elementos compartidos en Compose es que, en orden para compartir entre diferentes elementos componibles, la renderización de componible se eleva a una superposición de capas cuando se inicia la transición a que coincida con el destino. El efecto de esto es que se escapará el límites del elemento superior y las transformaciones de sus capas (por ejemplo, el valor alfa y la escala).
Se renderizará sobre otros elementos de la IU no compartidos, una vez que se realice la transición
Cuando finalice, se descartará el elemento de la superposición a su propio DrawScope
.
Para recortar un elemento compartido a una forma, usa el Modifier.clip()
estándar
. Colócalo después de 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 )
Si necesitas asegurarte de que un elemento compartido nunca se renderice fuera de un elemento superior
puedes configurar clipInOverlayDuringTransition
en sharedElement()
. De forma predeterminada, para los límites compartidos anidados, clipInOverlayDuringTransition
usa la ruta de acceso del clip del sharedBounds()
superior.
Para admitir la conservación de elementos específicos de la IU, como una barra inferior o una acción flotante
siempre en la parte superior durante una transición de elementos compartidos, usa
Modifier.renderInSharedTransitionScopeOverlay()
De forma predeterminada, este
mantiene el contenido en la superposición durante el tiempo en que se comparte
cuando la transición está activa.
Por ejemplo, en Jetsnack, el BottomAppBar
se debe colocar sobre el elemento compartido hasta que la pantalla no sea visible. Agrega el modificador
en el elemento componible lo mantiene elevado.
Sin |
Con |
---|---|
En ocasiones, tal vez quieras animar tu elemento no compartido componible
permanecerá por encima de los otros elementos componibles antes de la transición. En esos casos, utiliza
renderInSharedTransitionScopeOverlay().animateEnterExit()
para animar el
componible mientras se ejecuta la transición de elementos compartidos:
JetsnackBottomBar( modifier = Modifier .renderInSharedTransitionScopeOverlay( zIndexInOverlay = 1f, ) .animateEnterExit( enter = fadeIn() + slideInVertically { it }, exit = fadeOut() + slideOutVertically { it } ) )
En el caso poco frecuente de que quieras que tu elemento compartido no se renderice en una superposición, puedes establecer el renderInOverlayDuringTransition
en sharedElement()
como falso.
Notificar a los diseños del mismo nivel sobre los cambios en el tamaño de los elementos compartidos
De forma predeterminada, sharedBounds()
y sharedElement()
no notifican a la madre o el padre
de cualquier tamaño cambia a medida que pasa el diseño.
Para propagar los cambios de tamaño
al contenedor superior a medida que pasa
cambia el parámetro placeHolderSize
a PlaceHolderSize.animatedSize
. Hacer
y hace que el elemento aumente o se contraiga. Todos los demás elementos del diseño responden al cambio.
|
(Observa cómo los otros elementos de la lista se mueven hacia abajo en respuesta al crecimiento de un elemento) |
---|---|