Las transiciones de actividades en las apps de Material Design proporcionan conexiones visuales entre diferentes estados mediante el movimiento y las transformaciones entre elementos comunes. Puedes especificar animaciones personalizadas para entrar y salir de las transiciones y para las transiciones de elementos compartidos entre actividades.
Figura 1. Una transición con elementos compartidos
- Una transición de entrada determina cómo entran en escena las vistas en una actividad. Por ejemplo, en la transición de entrada
explode
, las vistas entran en escena desde el exterior y vuelan hacia el centro de la pantalla. - Una transición de salida determina cómo salen de escena las vistas en una actividad. Por ejemplo, en la transición de salida
explode
, las vistas salen de escena lejos del centro. - Una transición de elementos compartidos determina cómo las vistas que se comparten entre dos actividades realizan la transición entre estas. Por ejemplo, si dos actividades tienen la misma imagen en diferentes posiciones y tamaños, la transición de elementos compartidos
changeImageTransform
traduce y escala la imagen suavemente entre estas actividades.
Android admite las siguientes transiciones de entrada y salida:
explode
: Desplaza vistas hacia adentro o hacia afuera del centro de la escena.slide
: Desplaza vistas hacia adentro o hacia afuera de uno de los bordes de la escena.fade
: Agrega o quita una vista de la escena cambiando su opacidad.
Toda transición que extiende la clase Visibility
se admite como una transición de entrada o salida.
Para obtener más información, consulta la referencia de la API de la clase Transition
.
Android también admite las siguientes transiciones de elementos compartidos:
changeBounds
: Anima los cambios en los límites del diseño de las vistas de destino.changeClipBounds
: Anima los cambios en los límites de recorte de las vistas de destino.changeTransform
: Anima los cambios en escala y rotación de las vistas de destino.changeImageTransform
: Anima los cambios de tamaño y escala de las imágenes de destino.
Cuando habilitas las transiciones de actividades en tu app, la transición predeterminada entre difuminados se activa entre las actividades que ingresan y salen.
Figura 2: Una transición de escena con un elemento compartido
Para ver un código de ejemplo que anima entre actividades con elementos compartidos, consulta ActivitySceneTransitionBasic.
Comprueba la versión del sistema
Las API de transición de actividad están disponibles en Android 5.0 (API nivel 21) y versiones posteriores. Para conservar la compatibilidad con versiones anteriores de Android, comprueba el sistema version
en tiempo de ejecución antes de invocar las APIs para cualquiera de estas funciones:
Kotlin
// Check if we're running on Android 5.0 or higher if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { // Apply activity transition } else { // Swap without transition }
Java
// Check if we're running on Android 5.0 or higher if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { // Apply activity transition } else { // Swap without transition }
Cómo especificar transiciones personalizadas
Primero, habilita las transiciones de contenido de la ventana con el atributo android:windowActivityTransitions
cuando definas un estilo que herede del tema Material. También puedes especificar transiciones de entrada, salida y elementos compartidos en tu definición de estilo:
<style name="BaseAppTheme" parent="android:Theme.Material"> <!-- enable window content transitions --> <item name="android:windowActivityTransitions">true</item> <!-- specify enter and exit transitions --> <item name="android:windowEnterTransition">@transition/explode</item> <item name="android:windowExitTransition">@transition/explode</item> <!-- specify shared element transitions --> <item name="android:windowSharedElementEnterTransition"> @transition/change_image_transform</item> <item name="android:windowSharedElementExitTransition"> @transition/change_image_transform</item> </style>
La transición change_image_transform
en este ejemplo se define en la siguiente forma:
<!-- res/transition/change_image_transform.xml --> <!-- (see also Shared Transitions below) --> <transitionSet xmlns:android="http://schemas.android.com/apk/res/android"> <changeImageTransform/> </transitionSet>
El elemento changeImageTransform
corresponde a la clase ChangeImageTransform
. Para obtener más información, consulta la referencia de la API de Transition
.
Para habilitar las transiciones del contenido de la ventana en tu código, llama a la función Window.requestFeature()
:
Kotlin
// Inside your activity (if you did not enable transitions in your theme) with(window) { requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS) // Set an exit transition exitTransition = Explode() }
Java
// Inside your activity (if you did not enable transitions in your theme) getWindow().requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS); // Set an exit transition getWindow().setExitTransition(new Explode());
Para especificar transiciones en tu código, llama a estas funciones con un objeto Transition
:
Window.setEnterTransition()
Window.setExitTransition()
Window.setSharedElementEnterTransition()
Window.setSharedElementExitTransition()
Las funciones setExitTransition()
y setSharedElementExitTransition()
definen la transición de salida para la actividad de llamada. Las funciones setEnterTransition()
y setSharedElementEnterTransition()
definen la transición de entrada para la actividad llamada.
Para obtener el efecto completo de una transición, debes habilitar las transiciones del contenido de las ventanas tanto para las actividades que realizan la llamada como para aquellas que son invocadas. De lo contrario, la actividad que realiza la llamada comienza la transición de salida, pero luego se muestran las transiciones de ventana, como escalar o difuminar.
Para iniciar una transición de entrada lo antes posible, usa la función Window.setAllowEnterTransitionOverlap()
en la actividad llamada. Esto te permite tener transiciones de entrada más intensas.
Inicia una actividad mediante transiciones
Si habilitas transiciones y estableces una transición de salida para una actividad, la transición se activa cuando inicias otra actividad, como alguna de las siguientes:
Kotlin
startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this).toBundle())
Java
startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this).toBundle());
Si estableces una transición de entrada para la segunda actividad, esa transición también se activa cuando se inicia la actividad. Para inhabilitar las transiciones cuando inicias otra actividad, proporciona un paquete de opciones null
.
Cómo iniciar una actividad con un elemento compartido
Para realizar una animación de transición de pantallas entre dos actividades que tienen un elemento compartido, haz lo siguiente:
- Habilita las transiciones del contenido de las ventanas en tu tema.
- Especifica una transición de elementos compartidos en tu estilo.
- Cómo definir tu transición como un recurso XML.
- Asigna un nombre común para los elementos compartidos en ambos diseños con el atributo
android:transitionName
. - Usa la función
ActivityOptions.makeSceneTransitionAnimation()
.
Kotlin
// Get the element that receives the click event val imgContainerView = findViewById<View>(R.id.img_container) // Get the common element for the transition in this activity val androidRobotView = findViewById<View>(R.id.image_small) // Define a click listener imgContainerView.setOnClickListener( { val intent = Intent(this, Activity2::class.java) // Create the transition animation - the images in the layouts // of both activities are defined with android:transitionName="robot" val options = ActivityOptions .makeSceneTransitionAnimation(this, androidRobotView, "robot") // Start the new activity startActivity(intent, options.toBundle()) })
Java
// Get the element that receives the click event final View imgContainerView = findViewById(R.id.img_container); // Get the common element for the transition in this activity final View androidRobotView = findViewById(R.id.image_small); // Define a click listener imgContainerView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(this, Activity2.class); // Create the transition animation - the images in the layouts // of both activities are defined with android:transitionName="robot" ActivityOptions options = ActivityOptions .makeSceneTransitionAnimation(this, androidRobotView, "robot"); // Start the new activity startActivity(intent, options.toBundle()); } });
Para las vistas dinámicas compartidas que generas en tu código, usa la función View.setTransitionName()
a fin de especificar un nombre de elemento común en ambas actividades.
Para revertir la animación de transición de escena cuando termines la segunda actividad, llama a la función Activity.finishAfterTransition()
en lugar de Activity.finish()
.
Cómo iniciar una actividad con varios elementos compartidos
Para realizar una animación de transición de escena entre dos actividades que tienen más de un elemento compartido, define los elementos compartidos en ambos diseños con el atributo android:transitionName
(o usa la función View.setTransitionName()
en ambas actividades) y crea un objeto ActivityOptions
de la siguiente manera:
Kotlin
// Rename the Pair class from the Android framework to avoid a name clash import android.util.Pair as UtilPair ... val options = ActivityOptions.makeSceneTransitionAnimation(this, UtilPair.create(view1, "agreedName1"), UtilPair.create(view2, "agreedName2"))
Java
ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(this, Pair.create(view1, "agreedName1"), Pair.create(view2, "agreedName2"));