Conceptos básicos de animate*AsState
Anime valores individuales con suavidad
Conceptos básicos de animate*AsState es una lección gratuita de Android Academy en CoddyKit. Esta es la lección 2 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Android Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Android Academy incluye 4 lecciones en total.
Animar un único valor
La forma más sencilla de animar en Compose es la familia animate*AsState. Se le proporciona un valor objetivo y devuelve un State que anima suavemente desde el valor actual hasta el objetivo cada vez que este cambia.
Existe una variante para cada tipo habitual: animateFloatAsState, animateDpAsState, animateColorAsState, animateOffsetAsState y muchas más.
animateFloatAsState
animateFloatAsState anima un único Float. Un uso habitual es la opacidad (alpha). Cuando visible cambia, el alpha devuelto se desliza entre 0f y 1f.
Observe la palabra clave by: permite leer el State<Float> animado directamente como un Float normal.
@Composable
fun FadingLabel(visible: Boolean) {
val alpha by animateFloatAsState(
targetValue = if (visible) 1f else 0f,
label = "alpha"
)
Text(
"Hello",
modifier = Modifier.graphicsLayer { this.alpha = alpha }
)
}animateDpAsState
Los tamaños y desplazamientos de la interfaz usan Dp, así que utilice animateDpAsState para animar el padding, el tamaño o la posición.
Aquí, una caja crece de 80dp a 160dp al alternar el estado. Como pasamos el Dp animado a size(), la caja cambia de tamaño suavemente.
@Composable
fun GrowingBox(big: Boolean) {
val size by animateDpAsState(
targetValue = if (big) 160.dp else 80.dp,
label = "size"
)
Box(
Modifier
.size(size)
.background(Color.Blue)
)
}animateColorAsState
Para animar colores, use animateColorAsState. Interpola dentro del espacio de color para que las transiciones se vean suaves y naturales, en lugar de parpadear con tonos intermedios extraños.
Aquí, un punto de estado cambia entre rojo y verde según un valor booleano.
@Composable
fun StatusDot(online: Boolean) {
val color by animateColorAsState(
targetValue = if (online) Color(0xFF4CAF50) else Color(0xFFF44336),
label = "status-color"
)
Box(
Modifier
.size(16.dp)
.clip(CircleShape)
.background(color)
)
}Personalización con animationSpec
De forma predeterminada, estas funciones auxiliares usan un resorte suave. Pase un animationSpec para controlar la duración. Use tween para establecer una duración fija con una curva de aceleración.
Este panel se desliza durante 400ms con una curva suave que acelera y después desacelera.
@Composable
fun SlidingPanel(open: Boolean) {
val offset by animateDpAsState(
targetValue = if (open) 0.dp else 250.dp,
animationSpec = tween(
durationMillis = 400,
easing = FastOutSlowInEasing
),
label = "offset"
)
Box(Modifier.offset(x = offset)) { /* content */ }
}Curvas de aceleración
La aceleración determina cómo una animación acelera y desacelera. Compose incluye varias:
LinearEasing: velocidad constante (sensación mecánica).FastOutSlowInEasing: el valor predeterminado de Material; inicio rápido y final suave.LinearOutSlowInEasing: para elementos que entran en la pantalla.FastOutLinearInEasing: para elementos que salen.
Elegir la aceleración adecuada hace que el movimiento parezca intencionado, no robótico.
val progress by animateFloatAsState(
targetValue = if (done) 1f else 0f,
animationSpec = tween(500, easing = LinearOutSlowInEasing),
label = "progress"
)Especificaciones de los resortes
En lugar de una duración fija, puede usar un spring, que produce una sensación física y natural. Un resorte se define mediante dampingRatio (cuánto rebota) y stiffness (a qué velocidad).
Los resortes son muy útiles porque se adaptan suavemente incluso cuando el objetivo cambia durante la animación.
val scale by animateFloatAsState(
targetValue = if (active) 1.2f else 1f,
animationSpec = spring(
dampingRatio = Spring.DampingRatioMediumBouncy,
stiffness = Spring.StiffnessLow
),
label = "scale"
)Reaccionar al finalizar
A veces necesitará hacer algo cuando termine una animación, como ejecutar una devolución de llamada cuando un valor alcance su objetivo. animate*AsState acepta un finishedListener precisamente para eso.
val alpha by animateFloatAsState(
targetValue = if (gone) 0f else 1f,
label = "alpha",
finishedListener = { finalValue ->
if (finalValue == 0f) onFullyHidden()
}
)Animar varias propiedades
Puede combinar varias llamadas a animate*AsState para animar más de una propiedad a la vez. Cada una sigue su propio valor y, juntas, crean un efecto más elaborado.
Aquí, un chip cambia de escala y de color cuando se selecciona.
@Composable
fun SelectableChip(selected: Boolean, text: String) {
val scale by animateFloatAsState(if (selected) 1.1f else 1f, label = "s")
val bg by animateColorAsState(
if (selected) Color(0xFF3F51B5) else Color.LightGray,
label = "bg"
)
Box(
Modifier
.graphicsLayer { scaleX = scale; scaleY = scale }
.clip(RoundedCornerShape(16.dp))
.background(bg)
.padding(horizontal = 12.dp, vertical = 6.dp)
) { Text(text) }
}Un resorte en Kotlin puro
Para comprender mejor qué «hace» un resorte, aquí tiene una pequeña simulación en Kotlin puro. En cada paso, acerca un valor al objetivo aplicando cierta amortiguación, de forma similar a cómo el resorte de Compose converge hacia el valor objetivo a lo largo de muchos fotogramas.
fun main() {
var value = 0f
val target = 100f
var velocity = 0f
val stiffness = 0.1f
val damping = 0.6f
repeat(6) { step ->
val force = (target - value) * stiffness
velocity = (velocity + force) * damping
value += velocity
println("step $step -> ${"%.1f".format(value)}")
}
}Animar Int y Offset
La familia va más allá de los floats y los colores. Use animateIntAsState para valores enteros, como el objetivo de un contador de insignia, y animateOffsetAsState o animateIntOffsetAsState para animar la posición 2D en una sola llamada.
Aquí, un chip se desliza en diagonal mediante la animación de un IntOffset.
@Composable
fun SlidingChip(moved: Boolean) {
val pos by animateIntOffsetAsState(
targetValue = if (moved) IntOffset(120, 60) else IntOffset.Zero,
label = "pos"
)
Box(
Modifier
.offset { pos }
.size(40.dp)
.background(Color.Magenta)
)
}Comprobación rápida
Quiere animar suavemente el ancho de una caja, medido en Dp, cuando cambia un valor booleano. ¿Qué API es la más adecuada?
Repaso: animate*AsState
La familia animate*AsState es la opción principal para animar un único valor:
- Elija la variante con el tipo adecuado:
animateFloatAsState,animateDpAsState,animateColorAsState, etc. - Establezca un
targetValue; el resultado se anima hacia él cada vez que cambia. - Configure el movimiento con
animationSpecmediantetween+ aceleración ospring. - Combine varias funciones para animar varias propiedades a la vez.
- Use
finishedListenerpara reaccionar cuando termine una animación.
A continuación: animar la aparición y desaparición de contenido con AnimatedVisibility y las transiciones.
Preguntas frecuentes
¿La lección «Conceptos básicos de animate*AsState» es gratis?
Sí — el texto completo de «Conceptos básicos de animate*AsState» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Android Academy, actualiza a CoddyKit PRO. El curso de Android Academy incluye 4 lecciones en total.
¿Qué aprenderé en «Conceptos básicos de animate*AsState»?
Anime valores individuales con suavidad Practicas Android Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar Android Academy?
No se requiere experiencia previa. Android Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 2 de 4.
¿Cuánto tiempo toma la lección «Conceptos básicos de animate*AsState»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de Android Academy?
Sí. Cada lección de Android Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- Por qué son importantes las animaciones
- Conceptos básicos de animate*AsState
- AnimatedVisibility y transiciones
- Animaciones de gestos y resortes