Criando ícones animados no Android
Como criar ícones animados através de imagens vetoriais que irão incrementar a experiência do usuário a partir do Android Lollipop
De acordo com as especificações do Material Design:
“Animações podem existir dentro de todos os componentes de um aplicativo e em todas as escalas, desde ícones detalhados a transições-chave e ações.”
Um ícone de menu que suavemente se transforma em uma seta serve para duas funções: informar ao usuário e fasciná-lo quando uma animação é usada além do óbvio.
Mas antes de nos aprofundarmos nos ícones animados, precisamos entender alguns pontos importantes…
Bitmap x Vetor
Um bitmap representa uma imagem através de uma série de pixels coloridos. Já uma imagem vetorial é representada através de formas geométricas (pontos, linhas e curvas) utilizando cores.
Mas onde isso pode ser útil?
A principal utilidade de uma imagem vetorial é permitir escalar a imagem sem perder definição.
Um bitmap que foi feito para uma resolução de 100x100 tem uma ótima visualização nesta mesma resolução. Mas se for preciso visualizá-la em uma resolução maior, 500x500 por exemplo, ela terá que ser escalada e sua visualização não ficará muito boa.
Para resolvermos isso, temos uma opção de criar várias versões deste bitmap para cada densidade de tela, fazendo o tamanho do APK (Android Package) ficar cada vez maior.
Com imagens vetoriais, só precisamos criar o gráfico uma vez e ele será ajustado para as diversas densidades, reduzindo assim o tamanho do APK e simplificando a manutenção.
E onde os ícones animados entram na história?
Através das características do vetor, podemos criar animações que aplicam tranformações em imagens, sem distorcê-las, e ainda ampliar as possibilidades destas transformações.
VectorDrawable
Desde do Android API 21 (hoje nós temos uma Support Library que fornece o suporte a partir do Android API 7 em diante), podemos criar imagens vetoriais mais facilmente através da classe VectorDrawable.
Para criarmos uma imagem vetorial precisamos defini-la em um arquivo de recurso XML dentro da pasta res/drawable/.
O conteúdo do atributo pathData deve estar no padrão especificado para SVG (Scalable Vector Graphics) e é chamado de path.
Neste exemplo são utilizados apenas dois tipos de comandos:
- moveto, representado pelo M e estabelece um novo ponto de início.
- lineto, representado pelo L e desenha uma linha do ponto anterior para o novo ponto.
AnimatedVectorDrawable
Com um AnimatedVectorDrawable podemos animar as propriedades de um VectorDrawable, e para isto, basicamente precisamos de três arquivos XML:
- Um VectorDrawable <vector> na pasta res/drawable/
- Um ou mais ObjectAnimator <objectAnimator> ou AnimatorSet <set> na pasta res/anim/
- E um AnimatedVectorDrawable <animated-vector> na pasta res/drawable/
É possível animar atributos de um elemento <group>, <path> ou do próprio <vector>.
Elementos <group> são utilizados para agrupar paths ou subgrupos que precisam ser animados em conjunto.
- Quando definimos um VectorDrawable precisamos usar o atributo android:name e definir um nome único nos elementos que queremos animar, para então podermos referenciá-los das definições do Animator. Exemplo:
- O elemento <group> define um conjunto chamado “rotation”.
- Já o elemento <path> define as formas geométricas a serem desenhadas cujo nome é “menu”.
2.1. Definições da animação são representadas por objetos ObjectAnimator ou AnimatorSet.
- Neste exemplo, o Animator rotaciona o alvo em 180 graus com duração de 500 milisegundos.
2.2. O segundo Animator neste exemplo, transforma um path de uma forma para outra. Ambos os paths precisam ser compatíveis para a transformação: Eles devem ter a mesma quantidade de comandos e de parâmetros para cada comando.
3. As definições de um AnimatedVectorDrawable servem de ligação entre o VectorDrawable e as definições de animações.
Atualização
Você pode também, definir um VectorDrawable, ObjectAnimator e AnimatedVectorDrawable em um único arquivo. Veja este exemplo.
O AnimatedVectorDrawable é carregado como um Drawable comum, porém, é preciso chamar o método start() para iniciar a animação:
Um vez configurado corretamente, veremos o ícone animar desta forma (a duração da animação foi ampliada para 2 segundos):
Performance
- Evite usar comandos desnecessários. Simplifique seu path.
- Limite o tamanho do VectorDrawable. Esses Drawables são primeiro desenhados em um bitmap e depois é feito um upload para uma textura na GPU (unidade de processamento gráfico). Portanto, bitmaps maiores ocuparão mais memória e levarão mais tempo para fazer o upload. É recomendado usar VectorDrawables para ícones e botões pequenos com menos de 200dp.
- Atualize os atributos de um VectorDrawable somente o necessário. Quando não houver mudança de largura, altura ou opacidade (alpha), o framework será capaz de manter um cache de bitmap sem redesenhar o path ou fazer upload da textura para a GPU. Para o AnimatedVectorDrawable, esta abordagem de cache não ajudará. Portanto, mantenha as animações curtas e simples.
Confira o projeto de exemplo no github:
https://github.com/andremion/Android-Animated-Icons
Utilize ícones animados com moderação, deixe seu aplicativo mais bonito e forneça ao usuário uma melhor experiência de uso.