1. Introducción
Material Design es un sistema para crear productos digitales atractivos y llamativos. Mediante la unión de estilo, desarrollo de la marca, interacción y movimiento en un conjunto coherente de principios y componentes, los equipos de productos pueden alcanzar su máximo potencial de diseño.
Los componentes de Material (MDC) ayudan a los desarrolladores a implementar Material Design. MDC, creado por un equipo de ingenieros y diseñadores de UX en Google, cuenta con decenas de componentes de IU atractivos y funcionales, y está disponible para Android, iOS, la Web y Flutter.material.io/develop. |
¿Qué es el sistema de movimiento de Material para Android?
El sistema de movimiento de Material para Android es un conjunto de patrones de transición dentro de la biblioteca MDC-Android que puede ayudar a los usuarios a comprender una app y navegar por ella, como se describe en los lineamientos de Material Design.
Estos son los cuatro patrones de transición principales de Material:
- Transformación de contenedores: genera una transición entre elementos de la IU que incluyen un contenedor; crea una conexión visible entre dos elementos de la IU diferentes mediante una transformación fluida de un elemento en otro.
- Eje compartido: genera una transición entre elementos de la IU que tienen una relación espacial o de navegación; utiliza una transformación compartida en los ejes X, Y o Z para reforzar la relación entre elementos.
- Atenuación rápida: genera una transición entre elementos de la IU que no tienen una relación estrecha entre sí; utiliza una atenuación secuencial de entrada y salida, con la escala de un elemento nuevo.
- Atenuación: se utiliza para los elementos de la IU que entran a los límites de la pantalla o salen de estos.
La biblioteca de MDC-Android ofrece clases de transición para estos patrones, que se basan en la biblioteca de transición de AndroidX (androidx.transition
) y el framework de transición de Android (android.transition
):
AndroidX
- Disponible en el paquete
com.google.android.material.transition
- Compatible con el nivel de API 14 y versiones posteriores
- Admite fragmentos y vistas, pero no admite actividades ni ventanas
- Contiene correcciones de errores y comportamiento coherente en todos los niveles de API.
Framework
- Disponible en el paquete
com.google.android.material.transition.platform
- Compatible con el nivel de API 21 y versiones posteriores
- Admite fragmentos, vistas, actividades y ventanas.
- Las correcciones de errores no se adaptaron y podrían tener un comportamiento diferente en los niveles de API
En este codelab, usarás las transiciones de Material compiladas sobre la biblioteca de AndroidX, lo que significa que te enfocarás principalmente en los fragmentos y las vistas.
Qué compilarás
Este codelab te guiará en la compilación de algunas transiciones en una app de correo electrónico para Android de ejemplo llamada reply, con Kotlin, para demostrar cómo puedes usar las transiciones de la biblioteca MDC-Android para personalizar el aspecto de tu app.
Se te brindará el código de inicio para la app de Reply, e incorporarás en ella las transiciones de Material que se pueden observar en el siguiente GIF del codelab completo:
- Transición de transformación de contenedores desde la lista de direcciones de correo electrónico hasta la página de detalles del correo electrónico
- Transición de transformación de contenedores desde el BAF hasta la página para redactar correos electrónicos
- Transición de eje Z compartido desde el ícono de búsqueda hasta la página de la vista de búsqueda
- Transición de fundido entre las páginas de los buzones
- Transición de transformación de contenedores desde el chip de dirección de correo electrónico hasta la vista de tarjetas
Requisitos
- Conocimientos básicos sobre el desarrollo de Android y Kotlin
- Android Studio (descárgalo aquí si todavía no lo tienes)
- Un emulador o dispositivo Android (disponible a través de Android Studio)
- El código de muestra (consulta el siguiente paso)
¿Cómo calificarías tu nivel de experiencia con la compilación de apps para Android?
2. Configura tu entorno de desarrollo
Inicia Android Studio
Cuando abras Android Studio, debería aparecer una ventana con el título "Welcome to Android Studio". Sin embargo, si es la primera vez que inicias Android Studio, sigue los pasos del asistente de configuración de Android Studio con los valores predeterminados. En este paso, descargar e instalar los archivos necesarios puede tardar varios minutos. Puedes permitir que se ejecute en segundo plano mientras realizas los pasos de la siguiente sección.
Opción 1: Clona la app de inicio del codelab desde GitHub
Para clonar este codelab desde GitHub, ejecuta los siguientes comandos:
git clone https://github.com/material-components/material-components-android-motion-codelab.git cd material-components-android-motion-codelab
Opción 2: Descarga el archivo ZIP de la app de inicio del codelab
La app de inicio se encuentra en el directorio material-components-android-motion-codelab-develop
.
Cómo cargar el código de inicio en Android Studio
- Una vez que finalice el asistente de configuración y aparezca la ventana Welcome to Android Studio, haz clic en Open an existing Android Studio project.
- Navega hasta el directorio en el que instalaste el código de muestra y selecciona el directorio de muestra para abrir el proyecto.
- Espera un momento para que Android Studio compile y sincronice el proyecto, como se muestra en los indicadores de actividad de la parte inferior de la ventana de Android Studio.
- En este punto, es posible que Android Studio genere algunos errores de compilación, ya que te faltan el SDK de Android o las herramientas de compilación, como se muestra más abajo. Sigue las instrucciones de Android Studio para instalar o actualizar estos elementos y sincronizar tu proyecto. Si todavía tienes problemas, sigue la guía para actualizar herramientas con SDK Manager.
Verifica las dependencias del proyecto
El proyecto necesita una dependencia en la biblioteca de MDC-Android. El código de muestra que descargaste ya debería tener esta dependencia, pero verifiquemos la configuración para asegurarnos.
Navega al archivo build.gradle
del módulo app
y asegúrate de que el bloque dependencies
incluya una dependencia en MDC-Android:
implementation 'com.google.android.material:material:1.2.0'
Cómo ejecutar la app de inicio
- Asegúrate de que la configuración de compilación ubicada a la izquierda de la elección de dispositivo sea
app
. - Presiona el botón verde Run/Play para compilar y ejecutar la app.
- En la ventana Select Deployment Target, si ya tienes un dispositivo Android en la lista de dispositivos disponibles, ve al Paso 8. De lo contrario, haz clic en Create New Virtual Device.
- En la pantalla Select Hardware, selecciona un teléfono, por ejemplo, Pixel 3, y haz clic en Next.
- En la pantalla System Image, selecciona una versión reciente de Android, preferentemente, el nivel de API más alto. Si no está instalada, haz clic en el vínculo Download que aparece y completa la descarga.
- Haz clic en Next.
- En la pantalla Android Virtual Device (AVD), deja los ajustes tal como están y haz clic en Finish.
- Selecciona un dispositivo Android en el diálogo de destino de la implementación.
- Haz clic en Aceptar.
- Android Studio compila la app, la implementa y la abre automáticamente en el dispositivo de destino.
¡Listo! El código de inicio para la página principal de Reply debe estar ejecutándose en tu emulador. Deberías ver la carpeta Recibidos con una lista de correos electrónicos.
Disminuye las animaciones del dispositivo (opcional)
Como este codelab abarca transiciones rápidas y refinadas, puede resultar útil disminuir las animaciones del dispositivo para observar algunos de los detalles más sutiles de las transiciones durante la implementación. Esto se puede lograr con comandos de shell adb
o una tarjeta de Configuración rápida. Ten en cuenta que estos métodos para ralentizar las animaciones del dispositivo también afectarán las animaciones en el dispositivo fuera de la app de Reply.
Método 1: Comandos de shell de ADB
Para disminuir la velocidad de las animaciones del dispositivo hasta un factor de 10, puedes ejecutar los siguientes comandos desde la línea de comandos:
adb shell settings put global window_animation_scale 10
adb shell settings put global transition_animation_scale 10
adb shell settings put global animator_duration_scale 10
Para restablecer la velocidad de animación del dispositivo a la normalidad, ejecuta los siguientes comandos:
adb shell settings put global window_animation_scale 1
adb shell settings put global transition_animation_scale 1
adb shell settings put global animator_duration_scale 1
Método 2: Tarjeta de Configuración rápida
Como alternativa, para configurar la tarjeta de Configuración rápida, primero habilita la Configuración para desarrolladores en tu dispositivo si aún no lo hiciste:
- En el dispositivo, abre "Configuración" aplicación
- Desplázate hasta la parte inferior y haz clic en "Acerca del dispositivo emulado".
- Desplázate hasta la parte inferior y haz clic rápidamente en "Número de compilación". hasta que se habilite la Configuración para desarrolladores
Luego, haz lo siguiente en la opción "Configuración" del dispositivo para habilitar la tarjeta de Configuración rápida:
- Haz clic en el ícono de búsqueda o en la barra de búsqueda en la parte superior de la pantalla.
- Escribe "mosaicos" en el campo de búsqueda.
- Haz clic en las "tarjetas de configuración rápida para desarrolladores". fila
- Haz clic en la opción "Escala de animación de ventana". interruptor
Por último, a lo largo del codelab, desliza el panel de notificaciones del sistema desde la parte superior de la pantalla y usa el ícono para alternar entre las animaciones de velocidad lenta y normal.
3. Familiarízate con el código de la app de ejemplo
Echemos un vistazo al código. Proporcionamos una app que usa la biblioteca del componente de Jetpack Navigation para navegar entre diferentes fragmentos, todo dentro de una sola Activity, MainActivity:
- HomeFragment: Muestra una lista de correos electrónicos.
- EmailFragment: Muestra un solo correo electrónico completo.
- ComposeFragment: permite redactar un correo electrónico nuevo.
- SearchFragment: Muestra una vista de búsqueda.
navigation_graph.xml
Primero, para comprender cómo está configurado el gráfico de navegación de la app, abre navigation_graph.xml
en el directorio app -> src -> main -> res -> navigation
:
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/navigation_graph"
app:startDestination="@id/homeFragment">
<fragment
android:id="@+id/homeFragment"
android:name="com.materialstudies.reply.ui.home.HomeFragment"
android:label="HomeFragment">
<argument...>
<action
android:id="@+id/action_homeFragment_to_emailFragment"
app:destination="@id/emailFragment" />
</fragment>
<fragment
android:id="@+id/emailFragment"
android:name="com.materialstudies.reply.ui.email.EmailFragment"
android:label="EmailFragment">
<argument...>
</fragment>
<fragment
android:id="@+id/composeFragment"
android:name="com.materialstudies.reply.ui.compose.ComposeFragment"
android:label="ComposeFragment">
<argument...>
</fragment>
<fragment
android:id="@+id/searchFragment"
android:name="com.materialstudies.reply.ui.search.SearchFragment"
android:label="SearchFragment" />
<action
android:id="@+id/action_global_homeFragment"
app:destination="@+id/homeFragment"
app:launchSingleTop="true"
app:popUpTo="@+id/navigation_graph"
app:popUpToInclusive="true"/>
<action
android:id="@+id/action_global_composeFragment"
app:destination="@+id/composeFragment" />
<action
android:id="@+id/action_global_searchFragment"
app:destination="@+id/searchFragment" />
</navigation>
Observa cómo están presentes todos los fragmentos mencionados anteriormente, con el fragmento de lanzamiento predeterminado establecido en HomeFragment
a través de app:startDestination="@id/homeFragment"
. Esta definición XML del gráfico de destino del fragmento, así como las acciones, informa el código de navegación de Kotlin generado que encontrarás cuando conectes transiciones.
activity_main.xml
A continuación, observa el diseño de activity_main.xml
en el directorio app -> src -> main -> res -> layout
. Verás el NavHostFragment
que está configurado con el gráfico de navegación de arriba:
<fragment
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/navigation_graph"/>
Este NavHostFragment
ocupa toda la pantalla y controla todos los cambios de navegación de los fragmentos de pantalla completa en la app. La BottomAppBar
y su FloatingActionButton
anclada, también en activity_main.xml
, se disponen sobre el fragmento actual que muestra NavHostFragment
y, por lo tanto, se ocultan o se muestran según el destino del fragmento en el código de la app de ejemplo proporcionado.
Además, BottomNavDrawerFragment
en activity_main.xml
es un panel lateral inferior que contiene un menú para navegar entre los diferentes buzones de correo electrónico, que se muestra condicionalmente a través del botón del logotipo de Responder BottomAppBar
.
MainActivity.kt
Por último, para ver un ejemplo de una acción de navegación en uso, abre MainActivity.kt
en el directorio app -> src -> main -> java -> com.materialstudies.reply.ui
. Ubica la función navigateToSearch()
, que debería verse de la siguiente manera:
private fun navigateToSearch() {
val directions = SearchFragmentDirections.actionGlobalSearchFragment()
findNavController(R.id.nav_host_fragment).navigate(directions)
}
Aquí se muestra cómo puedes navegar a la página de vista de búsqueda sin ninguna transición personalizada. Durante este codelab, profundizarás en MainActivity de Reply y cuatro fragmentos principales para configurar transiciones de Material que funcionen en conjunto con las diversas acciones de navegación de la app.
Ahora que te familiarizaste con el código de partida, implementemos la primera transición.
4. Agrega una transición de transformación de contenedores desde la lista de direcciones de correo electrónico hasta la página de detalles del correo electrónico
En principio, agregarás una transición para la acción de hacer clic en un correo electrónico. Para este cambio de navegación, se prefiere el patrón de transformación de contenedores, ya que está diseñado para hacer transiciones entre elementos de la IU que incluyen un contenedor. Este patrón crea una conexión visible entre dos elementos de la IU.
Antes de agregar un fragmento de código, prueba ejecutar la app de Reply y hacer clic en un correo electrónico. Debería observarse un corte abrupto y simple, lo que implica que la pantalla se reemplaza por una sin transición:
Primero, agrega un atributo transitionName
en el MaterialCardView
de email_item_layout.xml
, como se muestra en el siguiente fragmento:
email_item_layout.xml
android:transitionName="@{@string/email_card_transition_name(email.id)}"
El nombre de la transición toma un recurso de cadenas con un parámetro. Debes usar el ID de cada correo electrónico para asegurarte de que cada transitionName
de nuestra EmailFragment
sea único.
Ahora que configuraste el nombre de transición de los elementos de la lista de direcciones de correo electrónico, haremos lo mismo en el diseño de los detalles del correo electrónico. En fragment_email.xml
, configura el transitionName
de MaterialCardView
en el siguiente recurso de cadenas:
fragment_email.xml
android:transitionName="@string/email_card_detail_transition_name"
En HomeFragment.kt
, reemplaza el código de onEmailClicked
por el siguiente fragmento para crear la asignación desde tu vista de inicio (elemento de la lista de direcciones de correo electrónico) y la vista final (pantalla de detalles de correo electrónico):
HomeFragment.kt
val emailCardDetailTransitionName = getString(R.string.email_card_detail_transition_name)
val extras = FragmentNavigatorExtras(cardView to emailCardDetailTransitionName)
val directions = HomeFragmentDirections.actionHomeFragmentToEmailFragment(email.id)
findNavController().navigate(directions, extras)
Ahora que ya configuraste la tubería, puedes crear una transformación de contenedor. En el método EmailFragment
onCreate
, configura sharedElementEnterTransition
en una instancia nueva de un MaterialContainerTransform
(importando la versión de com.google.android.material.transition
en lugar de la versión com.google.android.material.transition.platform
) agregando el siguiente fragmento:
EmailFragment.kt
sharedElementEnterTransition = MaterialContainerTransform().apply {
drawingViewId = R.id.nav_host_fragment
duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
scrimColor = Color.TRANSPARENT
setAllContainerColors(requireContext().themeColor(R.attr.colorSurface))
}
Ahora, prueba volver a ejecutar la app.
Todo comienza a verse increíble. Cuando haces clic en un correo electrónico de la lista, una transformación de contenedor debería expandir el elemento de la lista a una página de detalles en pantalla completa. Sin embargo, observa que presionar el botón Atrás no contrae el correo electrónico nuevamente en la lista. Además, la lista de direcciones de correo electrónico desaparece inmediatamente al comienzo de la transición y muestra el fondo de la ventana gris. Esto significa que aún no terminamos.
Para corregir la transición de retorno, agrega las siguientes dos líneas al método onViewCreated
en HomeFragment.kt
:
HomeFragment.kt
postponeEnterTransition()
view.doOnPreDraw { startPostponedEnterTransition() }
Vuelve a ejecutar la app. Si presionas el botón Atrás después de abrir un correo electrónico, este se contrae y vuelve a la lista. ¡Genial! Sigamos mejorando la animación.
El problema de que la lista de direcciones de correo electrónico desaparezca es que, cuando navegas a un nuevo fragmento usando el componente de Navigation, el fragmento actual se quita de inmediato y se reemplaza por el nuevo fragmento entrante. Para mantener visible la lista de direcciones de correo electrónico incluso después de reemplazarla, puedes agregar una transición de salida a HomeFragment
.
Agrega el siguiente fragmento al método onEmailClicked
de HomeFragment
para que la lista de correos electrónicos se reduzca sutilmente cuando salgas y se vuelva a ingresar cuando se vuelva a ingresar:
HomeFragment.kt
exitTransition = MaterialElevationScale(false).apply {
duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
}
reenterTransition = MaterialElevationScale(true).apply {
duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
}
A continuación, para garantizar que la transición de MaterialElevationScale
se aplique a toda la pantalla principal, en lugar de a cada una de las vistas individuales de la jerarquía, marca RecyclerView
en fragment_home.xml
como un grupo de transición.
fragment_home.xml
android:transitionGroup="true"
En esta etapa, la transformación de contenedores debe funcionar por completo. Cuando haces clic en un correo electrónico, el elemento de la lista se expande en una pantalla de detalles y, al mismo tiempo, se desvanece la lista de correos electrónicos. Cuando presionas el botón Atrás, la pantalla de detalles del correo electrónico se contrae en un elemento de la lista mientras se escala verticalmente la lista de correos electrónicos.
5. Agrega una transición de transformación de contenedores desde el BAF hasta la página para redactar correos electrónicos
Continuemos con la transformación de contenedores y agreguemos una transición del botón de acción flotante a ComposeFragment
. Para ello, expandamos el BAF a un correo electrónico nuevo que escribirá el usuario. Primero, vuelve a ejecutar la app y haz clic en el BAF a fin de verificar que no se hagan transiciones cuando se inicia la pantalla para redactar correos electrónicos.
Si bien usamos la misma clase de transición, la forma en que configuramos esta instancia será diferente, ya que nuestro BAF se encuentra en MainActivity
y nuestro ComposeFragment
se coloca dentro de nuestro contenedor de host de navegación MainActivity
.
En ComposeFragment.kt
, agrega el siguiente fragmento al método onViewCreated
y asegúrate de importar la versión androidx.transition
de Slide
.
ComposeFragment.kt
enterTransition = MaterialContainerTransform().apply {
startView = requireActivity().findViewById(R.id.fab)
endView = emailCardView
duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
scrimColor = Color.TRANSPARENT
containerColor = requireContext().themeColor(R.attr.colorSurface)
startContainerColor = requireContext().themeColor(R.attr.colorSecondary)
endContainerColor = requireContext().themeColor(R.attr.colorSurface)
}
returnTransition = Slide().apply {
duration = resources.getInteger(R.integer.reply_motion_duration_medium).toLong()
addTarget(R.id.email_card_view)
}
Además de los parámetros que se usaron para configurar nuestra transformación de contenedores anterior, startView
y endView
se establecen aquí de forma manual. En lugar de usar atributos transitionName
para permitir que el sistema de transición de Android sepa qué vistas se deben transformar, puedes especificarlas manualmente cuando sea necesario.
Ahora, vuelve a ejecutar la app. Deberías ver el BAF transformándose en la pantalla de redacción (consulta el GIF al final de este paso).
Al igual que en el paso anterior, debes agregar una transición a HomeFragment
para evitar que desaparezca después de que se quite y se reemplace por ComposeFragment
.
Copia el siguiente fragmento en el método navigateToCompose
en MainActivity
antes de llamar a NavController
navigate
.
MainActivity.kt
currentNavigationFragment?.apply {
exitTransition = MaterialElevationScale(false).apply {
duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
}
reenterTransition = MaterialElevationScale(true).apply {
duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
}
}
Ya terminaste con este paso. Deberías ver una transición desde el BAF hasta la pantalla para redactar de la siguiente manera:
6. Agrega una transición de eje Z compartido desde el ícono de búsqueda hasta la página de la vista de búsqueda
En este paso, agregaremos una transición desde el ícono de búsqueda hasta la vista de búsqueda directa en pantalla completa. Como no existe un contenedor persistente en este cambio de navegación, se puede usar una transición de eje Z compartido para reforzar la relación espacial entre las dos pantallas y para indicar que se mueva un nivel en dirección ascendente en la jerarquía de la app.
Antes de agregar más fragmentos de código, prueba ejecutar la app y presionar el ícono de búsqueda en la esquina inferior derecha de la pantalla. Debería aparecer la pantalla de la vista de búsqueda sin transición.
Para comenzar, busca el método navigateToSearch
en MainActivity
y agrega el siguiente fragmento de código antes de la llamada de método NavController
navigate
para configurar la salida del fragmento actual y volver a ingresar las transiciones del eje Z MaterialSharedAxis
.
MainActivity.kt
currentNavigationFragment?.apply {
exitTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true).apply {
duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
}
reenterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false).apply {
duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
}
}
A continuación, agrega el siguiente fragmento de código al método onCreate
en SearchFragment
, que configura sus transiciones de entrada y devolución de MaterialSharedAxis
.
SearchFragment.kt
enterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true).apply {
duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
}
returnTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false).apply {
duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
}
Por último, para garantizar que la transición de MaterialSharedAxis
se aplique a toda la pantalla de búsqueda, en lugar de a cada una de las vistas individuales de la jerarquía, marca LinearLayout
en fragment_search.xml
como un grupo de transición.
fragment_search.xml
android:transitionGroup="true"
Eso es todo. Ahora, prueba volver a ejecutar la app y presionar el ícono de búsqueda. Las pantallas de inicio y de la vista de búsqueda deben atenuarse y escalar, de manera simultánea, en el eje Z en profundidad. De esta manera, se crea un efecto fluido entre las dos pantallas.
7. Agrega una transición de atenuación entre las páginas de los buzones
En este paso, agregaremos una transición entre diferentes buzones. Como no deseamos enfatizar una relación espacial ni jerárquica, usaremos un fundido para realizar un "intercambio" sencillo entre las listas de correos electrónicos.
Antes de agregar más fragmentos de código, prueba ejecutar la app, presiona el logotipo de Reply en la barra inferior de la aplicación y cambia los buzones. La lista de correos electrónicos debería cambiar sin transición.
Para comenzar, busca el método navigateToHome
en MainActivity
y agrega el siguiente fragmento de código antes de la llamada de método NavController
navigate
para configurar la transición MaterialFadeThrough
de salida del fragmento actual.
MainActivity.kt
currentNavigationFragment?.apply {
exitTransition = MaterialFadeThrough().apply {
duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
}
}
A continuación, abre HomeFragment
. En onCreate
, establece el enterTransition
del fragmento en una nueva instancia de MaterialFadeThrough
.
HomeFragment.kt
enterTransition = MaterialFadeThrough().apply {
duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
}
Vuelve a ejecutar la app. Cuando abres el panel lateral inferior de navegación y cambias los buzones, se atenúa la lista actual de correos electrónicos y se reduce su escala, mientras que la lista nueva se atenúa y su escala se expande. ¡Genial!
8. Agrega una transición de transformación de contenedores desde el chip de dirección de correo electrónico a la vista de tarjetas
En este paso, agregarás una transición que transforme un chip en una tarjeta emergente. Aquí se usa una transformación de contenedor para informar al usuario que la acción realizada en la ventana emergente afectará al chip donde se originó la ventana emergente.
Antes de agregar un código, ejecuta la app de Reply, haz clic en un correo electrónico y, luego, en "Responder". BAF y, luego, intenta hacer clic en el chip de contacto de un destinatario. El chip debería desaparecer de inmediato y una tarjeta con las direcciones de correo electrónico de ese contacto debería aparecer sin animaciones.
Trabajarás en ComposeFragment
para este paso. En el diseño de ComposeFragment
, ya se agregaron los chips de destinatario (visibles de forma predeterminada) y una tarjeta de destinatario (invisible de forma predeterminada). Un chip de destinatario y esta tarjeta son las dos vistas entre las que crearás una transformación de contenedor.
Para comenzar, abre ComposeFragment
y busca el método expandChip
. Se llama a este método cuando se hace clic en el chip
proporcionado. Agrega el siguiente fragmento de código sobre las líneas que intercambian la visibilidad recipientCardView
y chip
, que activará la transformación de contenedor registrada a través de beginDelayedTransition
.
ComposeFragment.kt
val transform = MaterialContainerTransform().apply {
startView = chip
endView = binding.recipientCardView
scrimColor = Color.TRANSPARENT
endElevation = requireContext().resources.getDimension(
R.dimen.email_recipient_card_popup_elevation_compat
)
addTarget(binding.recipientCardView)
}
TransitionManager.beginDelayedTransition(binding.composeConstraintLayout, transform)
Si ejecutas la app ahora, el chip debería transformarse en una tarjeta de direcciones de correo electrónico para el destinatario. A continuación, configuraremos la transición de devolución para volver a contraer la tarjeta en el chip.
En el método collapseChip
de ComposeFragment
, agrega el siguiente fragmento de código para volver a contraer la tarjeta en el chip.
ComposeFragment.kt
val transform = MaterialContainerTransform().apply {
startView = binding.recipientCardView
endView = chip
scrimColor = Color.TRANSPARENT
startElevation = requireContext().resources.getDimension(
R.dimen.email_recipient_card_popup_elevation_compat
)
addTarget(chip)
}
TransitionManager.beginDelayedTransition(binding.composeConstraintLayout, transform)
Vuelve a ejecutar la app. Si haces clic en el chip, este se expandirá y se convertirá en una tarjeta, mientras que si haces clic en ella, la tarjeta se volverá a contraer en el chip. ¡Genial!
9. Todo listo
Con menos de 100 líneas de código Kotlin y algunos lenguajes de marcado XML básicos, la biblioteca de MDC-Android te ayudó a crear transiciones atractivas en una app existente que cumple con los lineamientos de Material Design y, además, tiene un aspecto y comportamiento coherentes en todos los dispositivos Android.
Próximos pasos
Si deseas obtener más información sobre el sistema de movimiento de Material, asegúrate de consultar la especificación y la documentación completa para desarrolladores, y prueba agregar algunas transiciones de Material a tu app.
Gracias por probar el sistema de movimiento de Material. Esperamos que hayas disfrutado de este codelab.