Tutorial: como criar animações em Android

No items found.
4/5/2020
Carlos Nicolau
Carlos Nicolau
Tech Lead

Sempre procurando conhecer mais sobre boas práticas no mundo Android.

Está sem tempo para ler? Aperte o play para escutar o artigo.

A dificuldade que temos em encontrar informações atualizadas e mais organizadas sobre animações Android me motivou a escrever este artigo e espero que o conteúdo seja útil também pra você.

A ideia aqui é começarmos pelo básico para a repetição dos assuntos se tornar algo familiar ao final deste assunto.

Bora?

Você pode encontrar o projeto completo no Github por aqui.

Lembrando que sempre que quiser visualizar no código a animação, basta mudar no AndroidManifest a tela de início para aquela que você deseja visualizar melhor. Estarão separadas por part1, part2, part3, etc.

Ao final deste assunto é para você chegar em algo parecido com isto: Link

O que abordaremos sobre o tema: 

  1. Criando animação básica Fade, Explose e Slide
  2. Criando uma Scene entre duas view de XML
  3. Criando animação entre duas Activities
  4. Configurando melhor o comportamento do SLIDE
  5. Animando mais de uma view por vez
  6. Esticando a imagem, rotacionando e cortando com animação
  7. Compartilhando animações entre telas com transitionName

Listas

  • Animação horizontal dando ênfase ao item central
  • Lista simples, animando em direções vários itens
  • Criando uma lista semelhante ao Netflix

1. Criando uma animação básica Fade, Explose e Slide

Neste primeiro exemplo, veremos como ficam as animações usando uma imagem do projeto. Neste caso, as 3 implementações são sobre: 

  • Fade
  • Explose
  • Slide

Basicamente, o código dentro de cada click é onde definimos nosso root que é a principal view e quais ações queremos tomar na imagem (Sumir e aparecer, em geral). 

Temos no Android a classe TransitionManager para nos quebrar esse galho.

TransitionManager.beginDelayedTransition(root, Fade())

Visualizando a animação do código acima, podemos ver o comportamento de cada item: Fade, Explose, Slide.

animações em android


Duas possíveis ações para ir para uma próxima tela.

  •  Podemos fazer via Scenes (disponibilizado pelo Android). Eu, particularmente, não acho que seja a melhor opção pois temos que colocar o método no xml para 2 arquivos de xml de view enxergarem o estado de cena que ele está, podendo também personalizar.
  • Outra maneira é setando de fato uma Transição antes de criar nossa Intent para a próxima tela.

2. Criando uma Scene entre duas view de XML

Criei uma activity chamada AnimationScene1Activity para visualizarmos melhor e dentro criei 2 cenas.

lateinit var scene: Scene
lateinit var nextScene: Scene

E declarei onde estão cada xml que deve ir quando clicado.

scene = Scene.getSceneForLayout(root, R.layout.activity_animation_scene_one, this)
nextScene = Scene.getSceneForLayout(root, R.layout.activity_animation_scene_one_two, this)

Valide em qual estado está para fazer a Cena. 

<p> CODE: https://gist.github.com/nicconicco/5ed6a76b3b94029ef35d0ce2e24b72f2.js</p>

No xml. Em cada click eu coloco a chamada do método:

android:onClick="changeScene"

E assim a animação padrão de entrada é a Fade. 

Vamos visualizar como ficou.


Beleza, agora vamos personalizar essa animação! 

Para isso precisamos criar um transition.xml


Eu nomeei o meu para my_transition.xml e o código é o seguinte:


<p> CODE: https://gist.github.com/nicconicco/e637a81e7293acc2e05866e12d6547b7.js</p>

Ali, eu seto qual imagem vai ter a animação e quais são os botões de ação. Tem o tempo para começar e quanto ela dura.

No meu changeScene adicionei o seguinte código:


<p> CODE: https://gist.github.com/nicconicco/c655e64609538fdea5a34abf0f41f370.js</p>

E passo nos dois métodos de go como segundo parâmetro:

TransitionManager.go(nextScene, transition)

TransitionManager.go(scene, transition)

O resultado fica assim:


Semelhante a ZoomIn, ZoomOut:

Ok! Agora vamos ver como funciona indo para outra atividade.

Podemos setar também a animação para Slide adicionando para mudar esse comportamento.


<p> CODE: https://gist.github.com/nicconicco/031ad38943aa9eded8bf13e6012133f6.js</p>

Confira o resultado:


3. Criando animação entre duas Activities.

Bom, aqui seguindo a documentação oficial vamos ter os seguintes passos:

1 — Criar um tema especificando a transição

2— Na tela que voltar, podemos setar via código a animação que desejamos.

Bora?

Criei a activity TransitionBetweenViewsActivity

Criei o tema e o código e ficou o seguinte: 


<p> CODE: https://gist.github.com/nicconicco/4622dbf229dbfc35d8b941edcbff47cf.js</p>

Uso ele no meu tema principal do AndroidManifest.

Código na ação do botão:


<p> CODE: https://gist.github.com/nicconicco/6bf70175bfbee221de19acbefa3f14c6.js</p>

No meu código de volta criei 2 arquivos novos de fade_in.xml e fade_out.xml dentro do package anim (crie essa pasta)


<p> CODE: https://gist.github.com/nicconicco/23a5502ef873b17428cb11d5bc77c0b9.js</p>

O código para escrever animações do projeto se chama overridePendingTransition, assim, clicando no botão voltar podemos personalizar.


<p> CODE: https://gist.github.com/nicconicco/6fbcf86c3e182cc23f5ec88b0e1ca51c.js</p>

E o resultado:

O ponto que podemos colocar como destaque é no tema BaseAppTheme

Eu coloquei em negrito para dar destaque que ele começa com a animação android:windowEnterTransition = slide_bottom e termina sua animação windowExitTransition = explode.

Agora vamos avançar para algo mais detalhado.

4. Configurando melhor o comportamento do SLIDE

No meu primeiro exemplo faltou dizer que com a propriedade Slide, podemos definir o comportamento dela. De onde vir, se da direita para esquerda, bottom para top, etc.

Para isso, vamos adicionar mais um botão e setar o comportamento passando no construtor de onde deve vir.

O código ficou:

/**

*    TransitionManager.beginDelayedTransition(root, Slide(Gravity.TOP))

*    TransitionManager.beginDelayedTransition(root, Slide(Gravity.BOTTOM))

*    TransitionManager.beginDelayedTransition(root, Slide(Gravity.START))

*/


TransitionManager.beginDelayedTransition(root, Slide(Gravity.END))


Veja o resultado:


5. Animando mais de uma view por vez

Agora vamos animar, mais de uma view e entender como pegar os filhos de uma view para animar cada um deles.

Criei a classe CoordinatedSlideActivity

Ao clicar no menu no canto direito, você vai fazer todas as animações da view que estiverem dentro. Para isso vamos usar o Slide indo no sentido Top.

Uma vez configurado o menu, vamos pegar nosso Root view e dentro dele, temos o método childCount que vai nos retornar quantos itens tem lá dentro.

Ai iremos pegar cada um desses elementos e fazer a animação.

O Código ficou assim:

<p> CODE: https://gist.github.com/nicconicco/326bd79aa481894b85e95b3f6c5463f2.js</p>


Resultado disso:

Se você olhar o xml vai ver que lá dentro tem 5 ImageView`s.

6. Esticando a imagem, rotacionando e cortando com animação

Aqui, o título já nos dá uma ideia do que vamos ver.

Criei a classe ChangeAnimationActivity

E dentro do click eu configuro como quero que minha animação se comporte:


<p> CODE: https://gist.github.com/nicconicco/18ba069aa68a75e091bc70c0f5880542.js</p>

O resultado:


Não tem muito o que detalhar. Mudei a largura e altura da imagem no eixo X e Y e rotacionando ela em 30 graus. Deixei comentada a última linha, mas você pode cortar a imagem se preferir. 

Pra você dar zoom na imagem, por exemplo, pode setar seu transition:

transitionSet.addTransition(ChangeImageTransform())


E setar em sua imagem:

image.scaleType = ImageView.ScaleType.CENTER

Resultado:

7. Compartilhando animações entre telas com transitionName

Vamos fazer uma animação para compartilhar um tipo de transição com nome. interessante para quando entramos no detalhe do produto. Depois mais a frente vamos fazer com listas.

As classes de referência sao: SharedAnimationActivity e SequenceAnimationActivity

Na classe Shared coloquei no evento do click o seguinte código:


<p> CODE: https://gist.github.com/nicconicco/a6961790f265ae8fb5d07065efcfad09.js</p>

Também comentei lá no BaseAppTheme como vem de padrão as animações de entrada e saída:

<!-- specify enter and exit transitions -->
<!--<item name="android:windowEnterTransition">@android:transition/slide_top</item>-->
<!--<item name="android:windowExitTransition">@android:transition/slide_bottom</item>-->


Tanto na imagem de entrada como de saída do detalhe, coloquei a seguinte tag android:transitionName=”robot_android” assim ele sabe que, vou começar nessa imagem com esses ids e ir para a segunda tela com o id tal. Bastante cuidado: o id deve ser único. 

E sem mais delongas, esse é o resultado: 


Aqui, não falarei sobre a volta pois já discutimos em tópicos anteriores.

Listas

Colocar animações nos componentes de lista não é algo super prazeroso, concorda? Por isso, peguei alguns exemplos que encontrei na internet adaptando para os meus objetivos sem muitos problemas. Você pode fazer o mesmo em seu projeto. 

Animação horizontal dando ênfase ao item central

Bom, agora vamos entrar no mundo de listas. Foquei em pesquisar exemplos reais e aqui está um tutorial que me chamou bastante atenção: Custom Android Views: Carousel RecyclerView

Nenhum segredo de implementação, com resultados bem legais para seções variadas (*coff coff Ifood*) e o código estará em animation_part7 


Resultado:


Lista simples: animando em direções vários itens

Um blog que fez uma sequência de animações me chamou bastante atenção também:

Enter animation using recyclerview and layoutanimation

Ele coloca um spinner controlando a lista para mostrar os diferentes tipos de layout. Eu acrescentei uma lista lateral com vários itens para a direita como exemplo apenas. 

Achei que isso se encaixa bem em alguns layouts que vemos em apps.

O resultado:


Criando uma lista semelhante ao Netflix

Explicando um pouco sobre esse componente. A ideia que vi em outros lugares é a de criar uma lista com um header por exemplo. E dentro dele outra lista na horizontal.

Existem várias maneiras de fazer isso.  Em questão de performace prefiro, particularmente, usar o RecyclerView e o ListAdapterDiffUtil. 

Então vamos lá. Seguindo a ideia da lista dentro de lista sabemos que vamos ter um “Pai” que vai ter seus “filhos” internos. Sendo assim, teremos 2 tipos de objetos como dito. Um Pai que tem um header e uma lista de filhos e dentro dele o filho tem as propriedades que serão escritas no detalhe do card do netflix.

Criei a classe NetflixActivity

Teremos que ter 2 adapters. Um para o Pai e outro para o Filho.

Criei com os nomes NetflixHeaderAdapter e NetflixCarouselAdapter.O Código de cada um ficou assim: 


Você pode ver com mais detalhes aqui pelo github.

NetflixHeaderAdapter


NetflixCarouselAdapter

Adicionei também no xml um AppBarLayout para termos nosso top com uma apresentação e ela ir sumindo conforme o scroll.

O trick agora foi adicionar ao clicar fazer a animação.


<p> CODE: https://gist.github.com/nicconicco/484a2d1a8533968c32d671efd8b52bd2.js</p>

Para isso, no detalhe do produto você precisa também setar o transitionName, conforme vimos acima. Passamos por bundle extras nosso transitionName.


<p> CODE: https://gist.github.com/nicconicco/e3035558ec2629d8d76203df4b350af3.js</p>

Criei um AppBarLayout com CollapsingBar no topo para ficar algo mais real. Ela tem uma toolbar dentro e uma imagem do nosso assunto aqui.

Codando e conectando tudo o resultado ficou assim!

Conclusão

É isso! Chegamos em uma telinha bem animada, com bastante personalizações e animações em mente, agora cabe a você adaptar ao seu projeto. 

Lembre-se de usar animações com responsabilidade, sem poluição. 

Espero que esse artigo seja útil pra você e suas animações. Ficou com alguma dúvida ou quer sugerir algo sobre o tema pra nossa comunidade? É só deixar nos comentários!


Aproveito para compartilhar alguns cursos que considero bem úteis sobre o tema:

- https://www.udemy.com/course/the-complete-android-animations-course/learn/practice/1033362

- https://www.udemy.com/course/curso-android-material-design/learn/lecture/8262654#overview

- https://codelabs.developers.google.com/codelabs/advanced-android-training-animations/index.html?index=..%2F..advanced-android-training#2


O que você achou deste conteúdo?
Quer receber nossos conteúdos?
Seu cadastro foi efetuado com sucesso! Enviaremos as novidades no seu email.
Oops! Something went wrong while submitting the form.