Introducción a las Animaciones en Jetpack Compose

Video thumbnail

Las animaciones son un punto fundamental hoy en día para dar presencia al momento de cargar datos, imágenes, transiciones entre pantallas, etc. Para los "android developers", las animaciones son clave para crear interfaces atractivas.

Tradicionalmente, esto se lograba con técnicas como ObjectAnimator y animaciones Drawable (que exploraremos en este artículo como métodos "Legacy"). Sin embargo, con la llegada de Jetpack Compose, la creación de animaciones ha evolucionado hacia un enfoque más declarativo y "composable".

Anteriormente quedamos en que como podemos usar Google Maps en Android Studio | Jetpack Compose

Animaciones con Jetpack Compose (el enfoque "Composable")

Con la introducción de Jetpack Compose, la forma de crear animaciones en Android ha evolucionado significativamente. Compose ofrece un enfoque declarativo y "composable" para las animaciones, lo que simplifica su implementación y las integra de manera más fluida con el resto de la UI construida con Compose.

A diferencia de los ObjectAnimator o las animaciones Drawable basadas en XML, en Jetpack Compose las animaciones se definen directamente en el código Kotlin utilizando funciones composables específicas para animación. Esto permite una mayor flexibilidad y una sintaxis más concisa.

Por ejemplo, para crear una animación de opacidad simple en Compose, podríamos usar animateFloatAsState:

@Composable
fun AnimatedVisibilityExample() {
    var visible by remember { mutableStateOf(true) }
    val alpha: Float by animateFloatAsState(
        targetValue = if (visible) 1f else 0f,
        animationSpec = tween(durationMillis = 1000)
    )
    Column {
        Button(onClick = { visible = !visible }) {
            Text("Toggle Visibility")
        }
        Box(
            modifier = Modifier
                .size(100.dp)
                .graphicsLayer(alpha = alpha)
                .background(Color.Blue)
        )
    }
}

En este ejemplo, animateFloatAsState crea un estado animado para la opacidad (alpha). Cuando el valor de visible cambia, la opacidad se anima suavemente entre 0f y 1f durante 1000 milisegundos. Este es solo un ejemplo básico; Jetpack Compose ofrece una rica API para animaciones más complejas, incluyendo transiciones de tamaño, color, posición y animaciones de listas.

Este enfoque "composable" es la forma recomendada para nuevos desarrollos en Android, ya que se alinea con la filosofía moderna de construcción de UI y mejora la legibilidad y mantenibilidad del código.

En esta sección vamos a dar un repaso rápido a las animaciones. Evaluaremos cuatro casos prácticos para entender cómo funcionan.

Para organizar los ejemplos, utilizaremos un Scaffold con una columna de tipo scrollable (verticalScroll). Antes de empezar, recuerda que debes instalar el paquete de Compose Animation en tu archivo de configuración, aunque el IDE te lo sugerirá automáticamente al escribir el código.

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContent {
            MyProyectAndroidTheme {
                Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
                    ScrollableColumnExample(innerPadding)
                }
            }
        }
    }
}
@Composable
fun ScrollableColumnExample(innerPadding: PaddingValues) {
    // 1. Creamos el estado del scroll
    val scrollState = rememberScrollState()
    Column(
        modifier = Modifier
            .fillMaxSize()
            .padding(innerPadding)
            // 2. Le aplicamos el modificador verticalScroll
            .verticalScroll(scrollState)
    ) {
        AnimatedVisibilityExample()
        VisibilityExpansionExample()
        ColorTransitionExample()
        ComplexStateAnimation()
    }
}

Y agregamos la siguiente dependencia:

// animations
implementation(libs.androidx.compose.animation)

1. Animación de Opacidad (animateFloatAsState)

El primer ejercicio es AnimatedVisibleExample. Aquí tenemos un botón y una caja azul (Box) donde el Alfa (la opacidad) es la propiedad animable.

  • Concepto clave: Utilizamos animateFloatAsState. Es similar a Flutter, donde existen animaciones implícitas y explícitas. En Compose, si queremos animar un número flotante (como la opacidad), usamos esta función para que mantenga el estado durante la recomposición.
  • Lógica: Definimos una variable visible con mutableStateOf y remember. Si visible es cierto, el alfa es 1 (visible); si no, es 0 (invisible).
  • Resultado: Al ser un cambio de alfa y no de tamaño, el espacio que ocupa el componente se mantiene, pero su visibilidad cambia suavemente de 0 a 1.
@Composable
fun AnimatedVisibilityExample() {
    var visible by remember { mutableStateOf(true) }
    val alpha: Float by animateFloatAsState(
        targetValue = if (visible) 1f else 0f,
        animationSpec = tween(durationMillis = 1000)
    )
    Column {
        Button(onClick = { visible = !visible }) {
            Text("Toggle Visibility")
        }
        Box(
            modifier = Modifier
                .size(100.dp)
                .graphicsLayer(alpha = alpha)
                .background(Color.Blue)
        )
    }
}
Animación para variar el alpha u opacidad de 0 a 1 con animateFloatAsState

2. Visibilidad Dinámica (AnimatedVisibility)

El segundo ejercicio permite mostrar u ocultar detalles desplazando el contenido. A diferencia del anterior, aquí el elemento sí desaparece del diseño, permitiendo que los demás componentes se desplacen.

  • Uso de Contenedores: Utilizamos el componente AnimatedVisibility. Este funciona de forma similar al AnimatedContainer de Flutter.
  • Encadenamiento de efectos: Lo interesante aquí es que puedes concatenar funciones. En este caso, usamos fadeIn + slideInVertically para la entrada, y fadeOut + slideOutVertically para la salida.
  • Resultado: El texto no solo aparece gradualmente, sino que se desliza hacia arriba o hacia abajo. Si quitas la concatenación, el efecto se vuelve brusco.
@Composable
fun VisibilityExpansionExample() {
    var isExpanded by remember { mutableStateOf(false) }
    Column(modifier = Modifier.padding(16.dp)) {
        Button(onClick = { isExpanded = !isExpanded }) {
            Text(if (isExpanded) "Ocultar Detalles" else "Mostrar Detalles")
        }
        // AnimatedVisibility maneja el fade y el slide por ti
        AnimatedVisibility(
            visible = isExpanded,
            enter = slideInVertically() + fadeIn(),
            exit = slideOutVertically() + fadeOut()
        ) {
            Text(
                "¡Sorpresa! Este texto aparece con un deslizamiento y desvanecimiento suaves.",
                modifier = Modifier.padding(top = 8.dp)
            )
        }
    }
}
Ocultar o mostrar contenido de manera animada mediante un slide con AnimatedVisibility

3. Animación de Colores (animateColorAsState)

En este ejercicio, activamos la animación directamente haciendo clic sobre la caja.

  • Cambio de color: Utilizamos animateColorAsState. Al igual que con los flotantes, esta función se encarga de transicionar suavemente entre dos colores (por ejemplo, de gris a azul).
  • Personalización: Podemos usar la propiedad tween para indicar la duración de la animación en milisegundos (ej. 500ms para medio segundo).
  • Interactividad: Aplicamos el modificador clickable a la caja para hacer el toggle del estado y cambiar tanto el color como el texto de forma reactiva.
@Composable
fun ColorTransitionExample() {
    var isSelected by remember { mutableStateOf(false) }
    // El color cambiará suavemente de Gris a Verde en 500ms
    val backgroundColor by animateColorAsState(
        targetValue = if (isSelected) Color(0xFF4CAF50) else Color.LightGray,
        animationSpec = tween(durationMillis = 500)
    )
    Box(
        modifier = Modifier
            .size(150.dp)
            .background(backgroundColor, shape = RoundedCornerShape(16.dp))
            .clickable { isSelected = !isSelected },
        contentAlignment = Alignment.Center
    ) {
        Text(if (isSelected) "Activo" else "Inactivo", color = Color.White)
    }
}
Variar el color de manera animada con ColorTransitionExample

4. Animaciones Complejas (updateTransition)

Para casos más avanzados donde queremos animar múltiples propiedades a la vez (dimensiones, rotación, forma), utilizamos las Transiciones.

  • updateTransition: Creamos una instancia de transición que rastrea un estado (en este caso, un enumerado con valores Small y Large).
  • Propiedades múltiples: Definimos el tamaño (size) y la rotación (rotation) dentro de la misma transición usando animateDp y animateFloat.
  • Lógica de estado: Si el estado es Small, definimos valores pequeños; si es Large, valores mayores.
  • Resultado: Al presionar el botón, la caja cambia de tamaño y rota simultáneamente. Esta es la "joya de la corona" para crear efectos visuales complejos de forma sincronizada y limpia.
@Composable
fun ComplexStateAnimation() {
    var currentState by remember { mutableStateOf(BoxState.Small) }
    val transition = updateTransition(targetState = currentState, label = "BoxTransition")
    // Definimos cómo cambian varias propiedades a la vez
    val size by transition.animateDp(label = "Size") { state ->
        if (state == BoxState.Small) 100.dp else 200.dp
    }
    val rotation by transition.animateFloat(label = "Rotation") { state ->
        if (state == BoxState.Small) 0f else 45f
    }
    Column(horizontalAlignment = Alignment.CenterHorizontally) {
        Button(onClick = {
            currentState = if (currentState == BoxState.Small) BoxState.Large else BoxState.Small
        }) {
            Text("Cambiar Tamaño y Rotación")
        }
        Spacer(modifier = Modifier.height(20.dp))
        Box(
            modifier = Modifier
                .size(size)
                .graphicsLayer(rotationZ = rotation)
                .background(Color.Magenta, RoundedCornerShape(8.dp))
        )
    }
}
enum class BoxState { Small, Large }
Animar otros parámetros como la rotación y tamaño con updateTransition

Animaciones con XML forma Legacy

A continuación, exploraremos las formas "Legacy" de crear animaciones en Android, como la siguiente, en la cual variamos la traslación en el eje de las Y y la opacidad de cero a uno:

traslación y opacidad Android animación

O está en la cual variamos solo la translación en el eje de las X:

traslación Android animación

O está en la cual variamos solo la opacidad:

opacidad Android animación

Es realmente fácil e inclusive las podemos ejecutar de manera paralela en un mismo elemento o recurso de una vista.

Uno de los grandes principios del Material Design es el uso de las animaciones como elemento fundamental para interactuar con el usuario mediante la UI dependiendo de la interactividad que realice el usuario con la aplicación.

Para las animaciones en Android que a la final son sencillas transiciones entre un estado y otro, vamos a hacer uso de los ObjectAnimator que proveen funcionalidades para animar vistas mediante un target u objetivo que viene siendo definido con los PropertyValuesHolder que son la forma en la que indicamos la propiedad y los valores que queremos animar...

Por ejemplo, la propiedad que queremos animar podría ser la opacidad y el valor de cero como valor inicial y el de uno para que quede completamente visible; entonces pasamos de un estado en la cual la vista se encuentra invisible a completamente visible (por supuesto, puede ser a la inversa o quedarnos en un punto medio y que sean semi visibles, etc).

Tipos de animaciones en Android: Animaciones mediante ObjectAnimator

Ya teniendo claro el marco teórico, que en resumen es definir la propiedad y los valores asociados, ahora veremos cuáles tipos de animaciones podemos hacer, es decir, que podemos animar y cuáles podrían ser sus valores.

Animando con la opacidad con PropertyValuesHolder

Podemos definir si queremos que las animaciones afecten la opacidad; por ejemplo si quisiéramos indicar que la vista pase de completamente oculta a visible debemos usar la propiedad ALPHA con valores flotantes entre cero y uno; el código en Kotlin sería:

PropertyValuesHolder.ofFloat(View.ALPHA, 0f, 1f))

O si queremos que la transición sea de de visible a oculta:

PropertyValuesHolder.ofFloat(View.ALPHA, 1f, 0f))

Animando con las rotaciones con PropertyValuesHolder

Para rotar las vistas podemos hacerlo en los ejes X y/o Y mediante las propiedades ROTATION_X y ROTATION_Y respectivamente; para rotar en el eje de las X 45 grados el código en Kotlin sería:

PropertyValuesHolder.ofFloat(View.ROTATION_X, 0f, 45f))

Para rotar 45 grados en el eje de las Y:

PropertyValuesHolder.ofFloat(View.ROTATION_Y, 0f, 45f))

En los ejemplo anteriores indicamos que queremos rotar desde los cero grados hasta los 45 grados (va de 0 a 360 grados).

En general, las rotaciones en las vistas no sería muy útiles a menos que quieras realizar algo muy específico.

Animando con los escalado con PropertyValuesHolder

Otra forma de realizar animaciones es con el escalado de las vistas en uno de los ejes X y Y cuyos valores van de cero para completamente oculta y a uno para el tamaño original, para escalar en el eje de las X el código en Kotlin es el siguiente:

ObjectAnimator.ofPropertyValuesHolder(bottomLay,
       PropertyValuesHolder.ofFloat(View.SCALE_X,
               0f, 1f))

Para el eje de las Y empleamos la propiedad SCALE_Y.

Animando con las traslaciones con PropertyValuesHolder:

Esta vista es muy útil cuando queremos realizar el efecto de entrada o salida como el de la imagen que mostramos en un inicio; para ello es recomendable que cuando sea de salida o entrada emplear el tamaño total de la vista, es decir, si la animación que queremos desarrollar es la de salida en el eje de las Y, entonces significa que la vista se está mostrando (no existe traslación, o la traslación en el eje de las Y es de cero) y el próximo estado, es la ocultación total de la vista; para ello debemos trasladar la vista hacia el fondo empleando el total del tamaño de la vista para ocultarlo hacia abajo:

Ocultar hacia abajo (Hide Bottom) animación

En base a lo explicado anteriormente tenemos:

PropertyValuesHolder.ofFloat(View.TRANSLATION_Y, 0f, hi.toFloat())

Ocultar hacia arriba (Hide Top) animación

Podemos jugar con los signos (positivo y negativo) para variar la translación de abajo hacia arriba o de arriba hacia abajo:

PropertyValuesHolder.ofFloat(View.TRANSLATION_Y, 0f, -hi.toFloat())

Ocultar hacia los lados(derecha izquierda) animación

Siguiendo con las translaciones en Android, para ocultar/mostrar hacia los lados, es decir de derecha a izquierda o izquierda a derecha, debemos emplear la propiedad View.TRANSLATION_X en vez de la de View.TRANSLATION_Y y en vez de emplear el algo de la vista, empleamos el ancho:

val wi = view.width
val iconAnim = ObjectAnimator.ofPropertyValuesHolder(view,
       PropertyValuesHolder.ofFloat(View.TRANSLATION_X, 0f, wi.toFloat()),

Finalmente un código de ejemplo base que podemos adaptar a cualquiera de los ejemplos que vimos anteriormente quedaría así con Kotlin:

val hi = view.height
view.visibility = View.VISIBLE
val iconAnim = ObjectAnimator.ofPropertyValuesHolder(view,
        PropertyValuesHolder.ofFloat(View.TRANSLATION_Y, hi.toFloat(), 0f))
iconAnim.duration = VIEW_ANIMATION
iconAnim.start()

Múltiples propiedades para realizar una animación más compleja en Android

Un punto muy importante es que podemos emplear uno o más propiedades para realizar las animaciones, es decir, podemos emplear uno dos o tres propiedades para la opacidad, o una opacidad y una traslación o como lo queramos configurar; para ello es el siguiente código en Kotlin que muestra cómo realizar una traslación en el eje de las Y junto con la opacidad:

val hi = view.height
view.visibility = View.VISIBLE
val iconAnim = ObjectAnimator.ofPropertyValuesHolder(view,
        PropertyValuesHolder.ofFloat(View.TRANSLATION_Y, hi.toFloat(), 0f),
        PropertyValuesHolder.ofFloat(View.ALPHA, 0f, 1f))
iconAnim.duration = VIEW_ANIMATION
iconAnim.start()

El código en Java quedaría de la siguiente forma:

view.setVisibility(View.VISIBLE);
Animator iconAnim = ObjectAnimator.ofPropertyValuesHolder(view,
            PropertyValuesHolder.ofFloat(View.TRANSLATION_Y, 0f, -
view.getHeight()),
            PropertyValuesHolder.ofFloat(View.ALPHA, 1f, 0f));
iconAnim.setDuration(VIEW_ANIMATION);
iconAnim.start();

Animaciones en Java y métodos/propiedades para el tiempo

Con Java no hay mucho más que decir, vemos que es un poco más de código, se emplean algunos métodos en vez de propiedades, pero por lo demás es el mismo funcionamiento y misma lógica; y esto se debe a que son muy parecidos ambos lenguajes de programación; al final tenemos el método setDuration() en Java o propiedad duration en Kotlin, que permite definir el tiempo en milisegundos que durará la animación:

val VIEW_ANIMATION: Long = 300

Y finalmente el método start() para iniciar la animación; existe un métodostartDelay en Kotlin y en Java el método setStartDelay() para indicar el delay o retraso de la animación, esto es muy útil si realizamos varias animaciones al mismo tiempo.

Listener para controlar los estados de las animaciones

Con los listener podemos saber cuando empieza una animación, cuando termina, si se repite o se cancela la misma y realizar alguna acción en consecuencia; por ejemplo, en el caso de las traslaciones para ocultar la vista mediante el desplazamiento o traslado de la misma ya sea en el eje de las X o de las Y, es un buen consejo ocultar la vista View.GONE una vez terminada la animación; para eso podemos emplear el método onAnimationEnd, de igual manera, para cuando comience la animación y la vista se encuentre oculta, podemos indicar en el método onAnimationStart que la vista sea visible otra vez para iniciar la animación View.VISIBLE; finalmente, el código en Kotlin quedaría:

iconAnim.addListener(object : Animator.AnimatorListener {
   override fun onAnimationStart(animation: Animator) {
   }
   override fun onAnimationEnd(animation: Animator) {
   }
   override fun onAnimationCancel(animation: Animator) {
   }
   override fun onAnimationRepeat(animation: Animator) {
   }
});

Y en Java tenemos:

iconAnim.addListener(new Animator.AnimatorListener() {
    @Override
    public void onAnimationStart(Animator animation) {
          bottomLay.setVisibility(View.VISIBLE);
    }
    @Override
    public void onAnimationEnd(Animator animation) {
    }
    @Override
    public void onAnimationCancel(Animator animation) {
    }
    @Override
    public void onAnimationRepeat(Animator animation) {
    }
});

En dónde iconAnim es una instancia de la clase ObjectAnimator que vimos en los ejemplos anteriores.

Tipos de animaciones en Android: Animaciones mediante Drawable

Otro tipo de efectos de transición o animaciones muy comunes son las empleadas mediante los recursos Drawable que a al final definen un XML con atributos y tags y a posterior se le ata a un elemento de la vista para definir el comportamiento de la animación.

Animaciones de vistas o de recursos (tween animation)

Este tipo de animaciones permite variar la posición, tamaño, rotación y opacidad/transparencia de un elemento de una vista; son ideales para ejecutar al inicio de una pantalla o cuando el usuario realiza alguna interacción sobre el contenido de la vista, como un click o algo similar; también son ideales para cambiar de estatus elementos de las vistas al terminar algún proceso.

Podemos modificar lo siguiente:

  • Duración Cuánto tiempo va a durar la animación.
  • Delay
  • Interpolación de tiempo Propiedades que se cambiarán en función del tiempo.

Entre algunas otras propiedades, pero estas son las más importantes; finalmente, para obtener una animación como la que vemos al final de esta sección, tenemos que conocer la siguiente información y de esta forma entender como trabaja.

Empleamos el siguiente recurso que lo tenemos registrado en:

res/anim/animacion.xml

El nombre animacion.xml es el nombre del recurso, puedes colocar el que quieras pero el mismo debe estar contenido dentro de res/anim/.

<set>: Contenedor padre de la animación

Un contenedor que contiene los elementos a animar (<alpha>, <alpha>, <scale>, <translate> y <rotate>) que contiene los siguientes atributos:

  • android:interpolatorEs la interpolación que vamos a aplicar en la animación.
  • android:shareInterpolatorSi es true se aplicará la misma interpolación a todos los hijos del elemento.
  • android:shareInterpolatorSi es true se aplicará la misma interpolación a todos los hijos del elemento.

<alpha>: Propiedad para la opacidad de las animaciones

Esta es una propiedad que permite definir el valor de opacidad del elemento en la animación, para eso contamos con un par de atributos:

  • android:fromAlpha: es un valor flotante que va de 0.0 para completamente invisible a 1.0 que es completamente visible; el valor medio es transparente amayo o menor grado.
  • android:toAlpha: es un valor flotante que va de 0.0 para completamente visible a 1.0 que es completamente invisible; el valor medio es transparente amayo o menor grado.

<scale>: Propiedad para la escala de las animaciones

Esta potente propiedad permite hacer el resizing o redimensiones de los elementos en la animación; para eso emplea un par de pivotes para que especifiques a partir de donde va a empezar el reescalado de la imagen pivotX y pivotY; por ejemplo si el valor tomado por estos pivotes es de 0, 0 respectivamente (arriba a la izquierda del elemento a animar) la animación empezará desde la parte de arriba a la derecha a reescalar; cuenta con los siguientes atributos:

  • android:fromXScale: 1.0 significa que no se va a reescalar en el eje de las X, otro valor indica que se redimensiona la imagen; es el valor en el cual se comenzará a reescalar.
  • android:toXScale: 1.0 significa que no se va a reescalar en el eje de las X, otro valor indica que se redimensiona la imagen; es el valor en el cual se terminará de reescalar.
  • android:fromYScale: 1.0 significa que no se va a reescalar en el eje de las Y, otro valor indica que se redimensiona la imagen; es el valor en el cual se comenzará a reescalar.
  • android:toYScale: 1.0 significa que no se va a reescalar en el eje de las Y, otro valor indica que se redimensiona la imagen; es el valor en el cual se terminará de reescalar.
  • android:pivotX: Permite especificar la coordenada X desde donde se va a empezar a reescalar.
  • android:pivotY: Permite especificar la coordenada Y desde donde se va a empezar a reescalar.

<translate>: Propiedad de las traslaciones de las animaciones

Esta propiedad también es muy útil, y permite realizar traslaciones entre los ejes X y Y, su funcionamiento es muy similar al del escalado, pero con el enfoque a las traslaciones; los valores van desde -100 a 100 por ciento (es decir, son porcentajes relativos al mismo elemento a animar si el valor es "%" y si el valor es "%p" indica que el valor relativo es al padre o elemento contenedor del elemento a animar); sus atributos son:

  • android:fromXDelta: Valor relativo al elemento a animar ("%") o al elemento padre ("%p") indica en porcentajes la traslación inicial en el eje X.
  • android:toXDelta: Valor relativo al elemento a animar ("%") o al elemento padre ("%p") indica en porcentajes la traslación final en el eje X.
  • android:fromYDelta: Valor relativo al elemento a animar ("%") o al elemento padre ("%p") indica en porcentajes la traslación inicial en el eje Y.
  • android:toYDelta: Valor relativo al elemento a animar ("%") o al elemento padre ("%p") indica en porcentajes la traslación final en el eje Y.

<rotate> Propiedad para las rotaciones de las animaciones

Permite realizar rotaciones; sus atributos son:

  • android:fromDegrees: Valor flotante que indica la posición de inicio en grados.
  • android:toDegrees: Valor flotante que indica la rotación final en grados.
  • android:pivotX: Al igual que ocurre con el escalado, este valor nos indica la posición X desde donde se ejecutará la rotación; puede ser relativo al elemento a animar ("%") o a su padre ("%p")Y.
  • android:pivotY: Al igual que ocurre con el escalado, este valor nos indica la posición Y donde se ejecutará la rotación; puede ser relativo al elemento a animar ("%") o a su padre ("%p")Y.

Finalmente ya con esto claro, presentamos la siguiente animación:

Animación de tipo recursos ejemplo

El recurso que empleamos es:

<set xmlns:android="http://schemas.android.com/apk/res/android">
    <scale
        android:duration="2000"
        android:fromXScale="3.0"
        android:fromYScale="2.0"
        android:toXScale="1.0"
        android:toYScale="1.0" />
    <rotate
        android:startOffset="2000"
        android:duration="2000"
        android:fromDegrees="0"
        android:toDegrees="360"
        android:pivotX="50%"
        android:pivotY="50%"/>
    <translate
        android:startOffset="4000"
        android:duration="2000"
        android:fromXDelta="0"
        android:fromYDelta="0"
        android:toXDelta="60"
        android:toYDelta="100" />
    <alpha
        android:startOffset="4000"
        android:duration="2000"
        android:fromAlpha="1"
        android:toAlpha="0" />
</set>

Luego el código en Kotlin sería:

AnimationUtils.loadAnimation(this, R.anim.animacion).also {
	hyperspaceJumpAnimation ->
	findViewById<TextView>(R.id.text_view).startAnimation(hyperspaceJumpAnimation)
}

Y en Java sería:

ImageView spaceshipImage = (ImageView) findViewById(R.id.spaceshipImage);
Animation hyperspaceJumpAnimation = AnimationUtils.loadAnimation(this, R.anim.hyperspace_jump);
spaceshipImage.startAnimation(hyperspaceJumpAnimation);

Por supuesto, debes de reemplazar el tipo de elemento y nombre del mismo por el tuyo que desees animar.

Conclusión

En esta entrada vimos como realizar sencillas transiciones o animaciones que son ideales para mostrar u ocultar elementos en una pantalla, pero esto va mucho más allá nos falta conversar como realizar transiciones entre pantalla (al darle click a un botón se muestre la conversión del botón en la nueva pantalla), como animar listados o los RecyclerView entre muchas otras cosas más que iremos viendo en próximas entregas.

Domina las animaciones en Jetpack Compose con esta guía práctica. Aprende a usar animateFloatAsState, AnimatedVisibility y transiciones complejas para crear interfaces dinámicas y profesionales en Android.

Acepto recibir anuncios de interes sobre este Blog.

Andrés Cruz

EN In english