1. Introdução
O Material Design é um sistema para criar produtos digitais bonitos e arrojados. Ao combinar estilo, branding, interação e movimento em um conjunto consistente de princípios e componentes, as equipes de produto podem atingir o maior potencial de design.
Os componentes do Material Design (MDC, na sigla em inglês) ajudam os desenvolvedores a implementar o Material Design. Criados por uma equipe de engenheiros e designers de UX do Google, os MDC apresentam dezenas de componentes de interface bonitos e funcionais e estão disponíveis para Android, iOS, Web e Flutter.material.io/develop |
O que é o sistema de movimento do Material Design para o Android?
O sistema de movimento do Material Design para Android é um conjunto de padrões de transição na biblioteca MDC-Android. Ele ajuda os usuários a entender e navegar em um app, conforme descrito nas diretrizes do Material Design.
Veja os quatro padrões principais de transição do Material Design:
- Transformação de contêiner: faz a transição entre elementos da interface que incluem um contêiner. Cria uma conexão visível entre dois elementos ao transformar um no outro.
- Eixo compartilhado: faz a transição entre elementos da interface que têm uma relação espacial ou de navegação. Usa uma transformação compartilhada nos eixos x, y ou z para reforçar a relação entre os elementos.
- Esmaecimento cruzado: faz a transição entre elementos da interface que não têm uma relação forte entre si. Usa o esmaecimento e a exibição gradual de forma sequencial com uma escala do elemento de entrada.
- Esmaecimento: usado para elementos da interface que entram ou saem dos limites da tela.
A biblioteca MDC-Android oferece classes de transição para esses padrões, criadas com base na biblioteca AndroidX Transition (androidx.transition) e no Android Transition Framework (android.transition):
AndroidX
- Disponível no pacote
com.google.android.material.transition - Compatível com o nível 14 da API e versões mais recentes
- Compatível com fragmentos e visualizações, mas não com atividades ou janelas
- Contém correções de bugs portadas e comportamento consistente em todos os níveis da API.
Framework
- Disponível no pacote
com.google.android.material.transition.platform - Compatível com o nível 21 da API ou mais recente
- Suporte para fragmentos, visualizações, atividades e janelas
- Correções de bugs não portadas e que podem ter comportamentos diferentes em vários níveis de API
Neste codelab, você vai usar as transições do Material Design com base na biblioteca AndroidX, ou seja, vai se concentrar principalmente em fragmentos e visualizações.
O que você vai criar
Este codelab orientará você na criação de algumas transições em um app de e-mails de exemplo do Android chamado Reply. Usaremos o Kotlin para demonstrar como usar as transições da biblioteca MDC-Android para personalizar a aparência e o uso do app.
Você receberá o código inicial do app Reply para incorporar nele as seguintes transições do Material Design, que podem ser vistas no GIF do codelab completo abaixo:
- Transição de transformação de contêiner da lista de e-mails para a página de detalhes
- Transição de transformação de contêiner do FAB para a página "Escrever e-mail"
- Transição de eixo z compartilhado do ícone de pesquisa para a página de visualização de pesquisa
- Transição de esmaecimento cruzado entre as páginas da caixa de e-mails
- Transição de transformação de contêiner do ícone de usuário com endereço de e-mail para a visualização de card

O que é necessário
- Conhecimento básico de desenvolvimento Android e Kotlin.
- Android Studio (faça o download dele aqui, caso ainda não tenha feito)
- Um dispositivo ou emulador Android (disponível no Android Studio)
- O exemplo de código (confira a próxima etapa)
Como você classificaria seu nível de experiência na criação de apps Android?
2. Configurar o ambiente de desenvolvimento
Iniciar o Android Studio
Ao abrir o Android Studio, você verá uma janela com o título "Welcome to Android Studio". No entanto, se você estiver iniciando essa ferramenta pela primeira vez, siga as etapas do assistente de configuração do Android Studio com os valores padrão. O sistema pode demorar vários minutos para fazer o download e instalar os arquivos necessários, então você pode deixar o programa em execução em segundo plano enquanto acompanha a próxima seção.
Opção 1: clonar o app inicial do codelab no GitHub
Para clonar este codelab no GitHub, execute estes comandos:
git clone https://github.com/material-components/material-components-android-motion-codelab.git cd material-components-android-motion-codelab
Opção 2: fazer o download do arquivo ZIP do app inicial do codelab
O app inicial está localizado no diretório material-components-android-motion-codelab-develop.
Carregar o código inicial no Android Studio
- Quando o assistente de configuração for concluído e a janela Welcome to Android Studio for exibida, clique em Open an existing Android Studio project.

- Acesse o diretório em que você instalou o exemplo de código e selecione o exemplo de diretório para abrir o projeto.
- Aguarde um pouco enquanto o Android Studio cria e sincroniza o projeto, conforme mostrado nos indicadores de atividade na parte inferior da janela.
- Como o SDK do Android ou as ferramentas de compilação não estão presentes, o Android Studio poderá encontrar alguns erros de compilação. Veja um exemplo a seguir. Siga as instruções no Android Studio para instalar/atualizar essas ferramentas e sincronizar o projeto. Se os problemas persistirem, siga o guia sobre como atualizar suas ferramentas com o SDK Manager.

Verificar as dependências do projeto
O projeto precisa de uma dependência na biblioteca MDC-Android. Provavelmente, o exemplo de código transferido por download já tem essa dependência listada, mas vamos conferir isso na configuração.
Navegue até o arquivo build.gradle do módulo app e confira se o bloco dependencies inclui uma dependência do MDC-Android:
implementation 'com.google.android.material:material:1.2.0'
Executar o app inicial
- Confira se a configuração do build à esquerda da opção de dispositivo é
app. - Pressione o botão verde Run / Play para criar e executar o app.

- Na janela Select Deployment Target, se você já tiver um dispositivo Android listado entre os dispositivos disponíveis, avance para a etapa 8. Caso contrário, clique em Create New Virtual Device.
- Na tela Select Hardware, selecione um smartphone, como o Pixel 3, e clique em Next.
- Na tela System Image, selecione uma versão recente do Android, de preferência o nível da API mais alto. Se ele não estiver instalado, clique no link Download exibido e faça o download.
- Clique em Next.
- Na tela Android Virtual Device (AVD), mantenha as configurações como estão e clique em Finish.
- Selecione um dispositivo Android na caixa de diálogo de destino de implantação.
- Clique em OK.
- O Android Studio cria o app, faz a implantação e o abre automaticamente no dispositivo de destino.
Pronto. O código inicial da página inicial do Reply será executado no emulador. Você vai acessar a Caixa de entrada com uma lista de e-mails.

Opcional: tornar as animações do dispositivo mais lentas
Como este codelab envolve transições rápidas, mas refinadas, pode ser útil desacelerar as animações do dispositivo para observar alguns dos detalhes mais delicados das transições durante a implementação. Isso pode ser feito com comandos do shell adb ou um bloco de Configurações Rápidas. Observe que esses métodos de desaceleramento de animações do dispositivo também afetam as animações fora do app Reply.
Método 1: comandos do shell do ADB
Para reduzir as animações do dispositivo em 10 vezes, execute os seguintes comandos na linha de comando:
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 redefinir a velocidade de animação do dispositivo e voltar ao normal, execute os seguintes 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: bloco de Configurações Rápidas
Se preferir, para configurar o bloco de Configurações rápidas, primeiro ative as Configurações do desenvolvedor no dispositivo, caso ainda não tenha feito isso:
- Abra o app "Configurações" do dispositivo.
- Role a tela para baixo e clique em "Sobre o dispositivo emulado".
- Role para baixo até a parte de baixo e clique rapidamente em "Número da versão" até que as Configurações do desenvolvedor sejam ativadas.
Em seguida, ainda no app "Configurações" do dispositivo, faça o seguinte para ativar o bloco das Configurações Rápidas:
- Clique no ícone de pesquisa ou na barra de pesquisa na parte de cima da tela
- Digite "blocos" no campo de pesquisa.
- Clique na linha "Blocos de desenvolvedor para configurações rápidas".
- Clique na chave "Escala de animação da janela".
Por fim, ao longo do codelab, deslize para baixo a aba de notificações do sistema na parte de cima da tela e use o ícone
para alternar entre animações em velocidade lenta e normal.
3. Conhecer o código do app de exemplo
Vamos analisar o código. Fornecemos um app que usa a biblioteca do componente de navegação do Jetpack para navegar entre alguns fragmentos diferentes, tudo em uma única atividade, a MainActivity:
- HomeFragment:mostra uma lista de e-mails.
- EmailFragment:exibe um único e-mail completo.
- ComposeFragment:permite escrever um novo e-mail.
- SearchFragment:mostra uma visualização de pesquisa.
navigation_graph.xml
Primeiro, para entender como o gráfico de navegação do app é configurado, abra navigation_graph.xml no diretório 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>
Observe como todos os fragmentos mencionados acima estão presentes, com o fragmento de inicialização padrão definido como HomeFragment via app:startDestination="@id/homeFragment". Essa definição XML do gráfico de destino do fragmento, assim como as ações, informa o código de navegação Kotlin gerado que você vai encontrar ao conectar transições.
activity_main.xml
Em seguida, confira o layout activity_main.xml no diretório app -> src -> main -> res -> layout. Você vai ver o NavHostFragment, que é configurado com o gráfico de navegação acima:
<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"/>
Esse NavHostFragment preenche a tela e processa todas as mudanças de navegação de fragmentos em tela cheia no app. O BottomAppBar e o FloatingActionButton ancorado, também em activity_main.xml, são dispostos sobre o fragmento atual mostrado pelo NavHostFragment e, portanto, serão mostrados ou ocultos dependendo do destino do fragmento pelo código do app de exemplo fornecido.
Além disso, o BottomNavDrawerFragment em activity_main.xml é um painel inferior que contém um menu para navegar entre as diferentes caixas de correio de e-mail, que é mostrado condicionalmente pelo botão do logotipo BottomAppBar Responder.
MainActivity.kt
Por fim, para ver um exemplo de ação de navegação em uso, abra o MainActivity.kt no diretório app -> src -> main -> java -> com.materialstudies.reply.ui. Localize a função navigateToSearch(), que deve ter esta aparência:
private fun navigateToSearch() {
val directions = SearchFragmentDirections.actionGlobalSearchFragment()
findNavController(R.id.nav_host_fragment).navigate(directions)
}
Isso mostra como você pode navegar até a página de visualização da pesquisa sem nenhuma transição personalizada. Durante este codelab, você vai conhecer a MainActivity e quatro fragmentos principais do Reply para configurar transições do Material Design que funcionam em conjunto com as várias ações de navegação do app.
Agora que você já conhece o código inicial, vamos implementar nossa primeira transição.
4. Adicionar uma transição de transformação de contêiner da lista de e-mails para a página de detalhes
Para começar, adicione uma transição ao clicar em um e-mail. Para essa mudança de navegação, o padrão de transformação de contêiner é adequado, já que foi projetado para transições entre elementos da interface que incluem um contêiner. Ele cria uma conexão visível entre dois elementos da interface.
Antes de adicionar qualquer código, execute o app Reply e clique em um e-mail. Ele fará um simples corte, ou seja, a tela será substituída sem transição:

Comece adicionando um atributo transitionName ao MaterialCardView em email_item_layout.xml, conforme mostrado no snippet a seguir:
email_item_layout.xml
android:transitionName="@{@string/email_card_transition_name(email.id)}"
O nome da transição usa um recurso de string com um parâmetro. Use o ID de cada e-mail para garantir que cada transitionName no nosso EmailFragment seja exclusivo.
Agora que você definiu o nome da transição do item da lista de e-mails, vamos fazer o mesmo no layout de detalhes do e-mail. Em fragment_email.xml, defina o transitionName da MaterialCardView como o seguinte recurso de string:
fragment_email.xml
android:transitionName="@string/email_card_detail_transition_name"
Em HomeFragment.kt, substitua o código em onEmailClicked pelo snippet abaixo para criar o mapeamento da visualização inicial (item da lista de e-mails) e da visualização final (tela de detalhes do e-mail):
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)
Agora que você configurou o encanamento, é possível criar uma transformação de contêiner. No método EmailFragment onCreate, defina sharedElementEnterTransition como uma nova instância de um MaterialContainerTransform (importando a versão com.google.android.material.transition em vez da com.google.android.material.transition.platform) adicionando o snippet a seguir:
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))
}
Agora, execute o app novamente.

Tudo está ficando ótimo. Ao clicar em um e-mail na lista de e-mails, uma transformação de contêiner deve expandir o item da lista para uma página de detalhes em tela cheia. No entanto, observe que, ao pressionar "Voltar", o e-mail não é recolhido de volta à lista. Além disso, a lista de e-mails desaparece imediatamente no início da transição, mostrando o plano de fundo cinza da janela. Ou seja, o trabalho ainda não terminou.
Para corrigir a transição de retorno, adicione as duas linhas a seguir ao método onViewCreated em HomeFragment.kt:
HomeFragment.kt
postponeEnterTransition()
view.doOnPreDraw { startPostponedEnterTransition() }
Tente executar o app novamente. Se você pressionar "Voltar" depois de abrir um e-mail, ele será recolhido na lista. Legal! Vamos continuar melhorando a animação.
O problema do desaparecimento da lista de e-mails ocorre porque, ao navegar para um novo fragmento usando o componente de navegação, o fragmento atual é removido imediatamente e substituído pelo novo fragmento recebido. Para manter a lista de e-mails visível mesmo depois de ser substituída, adicione uma transição de saída a HomeFragment.
Adicione o snippet abaixo ao método HomeFragment onEmailClicked para que a lista de e-mails seja escalonada horizontalmente sutilmente ao sair e volte a aparecer ao entrar novamente:
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()
}
Em seguida, para garantir que a transição MaterialElevationScale seja aplicada à tela inicial como um todo, em vez de a cada uma das visualizações individuais na hierarquia, marque o RecyclerView em fragment_home.xml como um grupo de transição.
fragment_home.xml
android:transitionGroup="true"
Nesta fase, você já tem uma transformação de contêiner em funcionamento. Se você clicar em um e-mail, o item da lista será expandido para uma tela de detalhes enquanto a lista de e-mails for ocultada. Se você pressionar "Voltar", a tela de detalhes do e-mail será recolhida e a lista de e-mails voltará a aparecer.

5. Adicionar uma transição de transformação de contêiner do FAB para a página "Escrever e-mail"
Vamos continuar a transformação de contêiner e adicionar uma transição do botão de ação flutuante para a ComposeFragment, expandindo o FAB para um novo e-mail que será escrito pelo usuário. Primeiro, execute o app novamente e clique no FAB. Você verá que não há transição ao abrir a tela "Escrever e-mail".

Embora usemos a mesma classe de transição, a maneira como configuramos essa instância será diferente, já que o FAB está em MainActivity e o ComposeFragment está dentro do contêiner de host de navegação MainActivity.
Em ComposeFragment.kt, adicione o seguinte snippet ao método onViewCreated, importando a versão 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)
}
Além dos parâmetros usados para configurar nossa transformação de contêiner anterior, startView e endView estão sendo definidos manualmente aqui. Em vez de usar atributos transitionName para informar ao sistema de transição do Android quais visualizações precisam ser transformadas, você pode especificar isso manualmente quando necessário.
Agora, execute o app novamente. Você vai ver o FAB se transformando na tela de composição (confira o GIF no final desta etapa).
Semelhante à etapa anterior, você precisa adicionar uma transição a HomeFragment para evitar que ele desapareça depois de ser removido e substituído por ComposeFragment.
Copie o snippet abaixo no método navigateToCompose em MainActivity antes da chamada 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()
}
}
Pronto, concluímos esta etapa. Agora você tem uma transição do FAB para a tela "Escrever e-mail" com a seguinte aparência:

6. Adicionar uma transição de eixo z compartilhado do ícone de pesquisa para a página de visualização de pesquisa
Nesta etapa, adicionaremos uma transição do ícone de pesquisa para a visualização de pesquisa em tela cheia. Como não há um contêiner persistente envolvido nessa mudança de navegação, podemos usar uma transição de eixo z compartilhado para reforçar a relação espacial entre as duas telas e indicar o movimento para um nível acima na hierarquia do app.
Antes de adicionar mais código, execute o app e toque no ícone de pesquisa no canto inferior direito da tela. Essa ação exibirá a tela de visualização da pesquisa sem transição.

Para começar, encontre o método navigateToSearch em MainActivity e adicione o snippet de código a seguir antes da chamada do método NavController navigate para configurar as transições de saída e reentrada do eixo Z MaterialSharedAxis do fragmento atual.
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()
}
}
Em seguida, adicione o snippet de código a seguir ao método onCreate em SearchFragment, que configura as transições de entrada e retorno 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 fim, para garantir que a transição MaterialSharedAxis seja aplicada à tela de pesquisa como um todo, em vez de a cada uma das visualizações individuais na hierarquia, marque o LinearLayout em fragment_search.xml como um grupo de transição.
fragment_search.xml
android:transitionGroup="true"
Pronto! Agora, execute novamente o app e toque no ícone de pesquisa. As telas inicial e de visualização da pesquisa serão esmaecidas e redimensionadas simultaneamente ao longo do eixo z em profundidade, criando um efeito contínuo entre as duas telas.

7. Adicionar uma transição de esmaecimento cruzado entre as páginas da caixa de e-mails
Nesta etapa, adicionaremos uma transição entre caixas de e-mails diferentes. Como não queremos enfatizar uma relação espacial ou hierárquica, usaremos um esmaecimento cruzado para fazer uma "troca" simples entre as listas de e-mails.
Antes de adicionar qualquer outro código, tente executar o app. Toque no logotipo do Reply na barra de apps inferior e mude de caixa de e-mails. A lista mudará sem nenhuma transição.

Para começar, encontre o método navigateToHome em MainActivity e adicione o snippet de código a seguir antes da chamada de método NavController navigate para configurar a transição de saída MaterialFadeThrough do fragmento atual.
MainActivity.kt
currentNavigationFragment?.apply {
exitTransition = MaterialFadeThrough().apply {
duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
}
}
Em seguida, abra HomeFragment. Em onCreate, defina o enterTransition do fragmento como uma nova instância de MaterialFadeThrough.
HomeFragment.kt
enterTransition = MaterialFadeThrough().apply {
duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
}
Execute o app novamente. Quando você abrir a gaveta de navegação inferior e mudar de caixa de e-mails, a lista de e-mails atual será esmaecida enquanto a nova lista é exibida. Legal!

8. Adicionar uma transição de transformação de contêiner do ícone do endereço de e-mail para a visualização em card
Nesta etapa, você vai adicionar uma transição que transforma um ícone em um card pop-up. Uma transformação de contêiner é usada aqui para informar ao usuário que a ação realizada no pop-up vai afetar o ícone de origem dele.
Antes de adicionar qualquer código, execute o app Reply, clique em um e-mail, clique no botão de ação flutuante "Responder" e tente clicar no ícone de contato de um destinatário. O ícone vai desaparecer instantaneamente, e um card com os endereços de e-mail desse contato vai aparecer sem animações.

Você vai trabalhar em ComposeFragment nesta etapa. Já adicionados no layout ComposeFragment estão os chips de destinatário (visíveis por padrão) e um card de destinatário (invisível por padrão). Um ícone de destinatário e este card são as duas visualizações entre as quais você vai criar uma transformação de contêiner.
Para começar, abra ComposeFragment e encontre o método expandChip. Esse método é chamado quando o chip fornecido é clicado. Adicione o snippet de código a seguir acima das linhas que trocam a visibilidade de recipientCardView e chip, o que vai acionar a transformação de contêiner registrada via 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)
Se você executar o app agora, o ícone vai se transformar em um card com os endereços de e-mail do destinatário. Em seguida, vamos configurar a transição de retorno para recolher o card de volta ao ícone.
No método collapseChip em ComposeFragment, adicione o snippet de código abaixo para recolher o card de volta ao ícone.
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)
Execute o app novamente. Clicar no ícone vai expandir o ícone para um card, e clicar no card vai recolher o card de volta para o ícone. Legal!

9. Tudo pronto
Usando menos de 100 linhas de código Kotlin e algumas marcações XML básicas, a biblioteca MDC-Android ajudou você a criar transições bonitas em um app atual seguindo as diretrizes do Material Design. Além disso, a aparência e o comportamento das transições são consistentes em todos os dispositivos Android.

Próximas etapas
Para ver mais informações sobre o sistema de movimento do Material Design, consulte as especificações e a documentação completa do desenvolvedor (links em inglês). Tente adicionar algumas transições do Material Design ao seu app.
Agradecemos por testar o movimento do Material Design. Esperamos que tenha gostado deste codelab.