Os objetos na tela geralmente precisam ser reposicionados devido à interação ou processamento do usuário em segundo plano. Em vez de atualizar imediatamente a posição do objeto, o que faz com que ele pisque de uma área para outra, use uma animação para mover o objeto da posição inicial para a final.
Uma maneira de o Android permitir reposicionar os objetos de visualização na tela é
usando ObjectAnimator
. Você informa a posição final em que
quer que o objeto fique, bem como a duração da animação. Também
é possível usar interpoladores de tempo para controlar a aceleração ou desaceleração da
animação.
Alterar a posição da visualização com o ObjectAnimator
A API ObjectAnimator
oferece uma maneira de mudar as propriedades de uma visualização com uma duração específica.
Ela contém métodos estáticos para criar instâncias do ObjectAnimator
, dependendo do
tipo de atributo que você está animando. Ao reposicionar suas visualizações na
tela, use os atributos translationX
e translationY
.
Confira um exemplo de uma ObjectAnimator
que move a visualização para uma posição a 100
pixels da esquerda da tela em 2 segundos:
Kotlin
ObjectAnimator.ofFloat(view, "translationX", 100f).apply { duration = 2000 start() }
Java
ObjectAnimator animation = ObjectAnimator.ofFloat(view, "translationX", 100f); animation.setDuration(2000); animation.start();
Este exemplo usa o método
ObjectAnimator.ofFloat()
, porque os valores de translação precisam ser flutuantes. O primeiro parâmetro é
a visualização que você quer animar. O segundo parâmetro é a propriedade que você está animando. Como a visualização precisa se mover horizontalmente, a propriedade
translationX
é usada. O último parâmetro é o valor final da animação. Nesse
exemplo, o valor de 100 indica uma posição com muitos pixels da esquerda
da tela.
O próximo método especifica quanto tempo a animação leva, em milissegundos. Neste exemplo, a animação é executada por 2 segundos (2.000 milissegundos).
O último método faz com que a animação seja executada, o que atualiza a posição da visualização na tela.
Para saber mais sobre como usar ObjectAnimator
, consulte Animar usando
o ObjectAnimator.
Adicionar movimento curvo
Embora o uso do ObjectAnimator
seja conveniente, por padrão, ele reposiciona a
visualização ao longo de uma linha reta entre os pontos inicial e final. O Material Design
depende de curvas para o movimento espacial de objetos na tela e do
tempo de uma animação. O uso de movimentos curvos dá ao app uma sensação mais material
e torna as animações mais interessantes.
Definir seu próprio caminho
A classe ObjectAnimator
tem construtores que permitem animar coordenadas
usando duas ou mais propriedades simultaneamente com um caminho. Por
exemplo, o animador abaixo usa um objeto
Path
para animar as propriedades X e Y
de uma visualização:
Kotlin
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { val path = Path().apply { arcTo(0f, 0f, 1000f, 1000f, 270f, -180f, true) } val animator = ObjectAnimator.ofFloat(view, View.X, View.Y, path).apply { duration = 2000 start() } } else { // Create animator without using curved path }
Java
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { Path path = new Path(); path.arcTo(0f, 0f, 1000f, 1000f, 270f, -180f, true); ObjectAnimator animator = ObjectAnimator.ofFloat(view, View.X, View.Y, path); animator.setDuration(2000); animator.start(); } else { // Create animator without using curved path }
Veja a aparência da animação em arco:
Figura 1. Uma animação de caminho em curva.
Um Interpolator
é uma implementação de uma curva de easing. Consulte a
documentação do Material Design
para saber mais sobre o conceito de curvas de easing. Uma Interpolator
define como valores específicos em uma animação são calculados como uma função de
tempo. O sistema fornece recursos XML para as três curvas básicas na
especificação do Material Design:
@interpolator/fast_out_linear_in.xml
@interpolator/fast_out_slow_in.xml
@interpolator/linear_out_slow_in.xml
Usar o PathInterpolator
A classe
PathInterpolator
é um interpolador introduzido no Android 5.0 (nível 21 da API). Ela é baseada em uma
curva de Bézier ou em um
objeto Path
. Os exemplos do Android na documentação do Material Design para
easing
usam PathInterpolator
.
PathInterpolator
tem construtores baseados em diferentes tipos de curvas de Bézier.
Todas as curvas de Bézier têm pontos de início e término fixados em (0,0)
e (1,1)
,
respectivamente. Os outros argumentos do construtor dependem do tipo de curva de Bézier
que está sendo criado.
Por exemplo, para uma curva quadrática de Bézier, apenas as coordenadas X e Y de um ponto de controle são necessárias:
Kotlin
val myInterpolator = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { PathInterpolator(0.67f, 0.33f) } else { LinearInterpolator() }
Java
Interpolator myInterpolator = null; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { myInterpolator = new PathInterpolator(0.67f, 0.33f); } else { myInterpolator = new LinearInterpolator(); }
Isso produz uma curva de easing que começa rapidamente e desacelera à medida que se aproxima do fim.
O construtor cúbico de Bézier tem pontos de início e término fixos de maneira semelhante, mas exige dois pontos de controle:
Kotlin
val myInterpolator = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { PathInterpolator(0.5f, 0.7f, 0.1f, 1.0f) } else { LinearInterpolator() }
Java
Interpolator myInterpolator = null; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { myInterpolator = new PathInterpolator(0.5f, 0.7f, 0.1f, 1.0f); } else { myInterpolator = new LinearInterpolator(); }
Essa é uma implementação da curva de easing de aceleração enfatizada (link em inglês) do Material Design.
Para ter mais controle, uma Path
arbitrária pode ser usada para definir a curva:
Kotlin
val myInterpolator = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { val path = Path().apply { moveTo(0.0f, 0.0f) cubicTo(0.5f, 0.7f, 0.1f, 1.0f, 1.0f, 1.0f) } PathInterpolator(path) } else { LinearInterpolator() }
Java
Interpolator myInterpolator = null; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { Path path = new Path(); path.moveTo(0.0f, 0.0f); path.cubicTo(0.5f, 0.7f, 0.1f, 1.0f, 1.0f, 1.0f); myInterpolator = new PathInterpolator(path); } else { myInterpolator = new LinearInterpolator(); }
Isso produz a mesma curva de easing do exemplo de Bézier cúbico, mas com o uso de um
Path
.
Você também pode definir um interpolador de caminho como um recurso XML:
<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
android:controlX1="0.5"
android:controlY1="0.7"
android:controlX2="0.1f"
android:controlY2="1.0f"/>
Depois de criar um objeto PathInterpolator
, você pode transmiti-lo para o
método
Animator.setInterpolator()
. O Animator
usa o interpolador para determinar a curva de tempo ou
de caminho quando é iniciado.
Kotlin
val animation = ObjectAnimator.ofFloat(view, "translationX", 100f).apply { interpolator = myInterpolator start() }
Java
ObjectAnimator animation = ObjectAnimator.ofFloat(view, "translationX", 100f); animation.setInterpolator(myInterpolator); animation.start();