Baseado em física movimento é impulsionado pela força. A força elástica é uma força que orienta interatividade e movimento. Uma força elástica tem as seguintes propriedades: o amortecimento e a rigidez. Em uma animação baseada em mola, o valor e a a velocidade é calculada com base na força elástica aplicada em cada frame.
Se você quiser que as animações do seu app desacelerem em apenas uma direção, use um modelo baseado em atrito animação de rolagem como alternativa.
Ciclo de vida de uma animação de mola
Em uma animação baseada em mola, o SpringForce
permite personalizar a rigidez da mola, a proporção de amortecimento e a
na posição final. Assim que a animação começar, a força elástica será atualizada
o valor da animação e a velocidade em cada frame. A animação continua
até que a força elástica atinja um equilíbrio.
Por exemplo, se você arrastar o ícone de um app pela tela e depois soltá-lo ao levantar o dedo do ícone, o ícone volta para o estado original por uma força invisível, mas familiar.
A Figura 1 demonstra um efeito de mola semelhante. O sinal de adição (+) na coluna meio do círculo indica a força aplicada por meio de um gesto de toque.
![Liberação da mola](https://developer.android.com/static/images/guide/topics/graphics/spring-release.gif?authuser=9&hl=pt)
Criar uma animação de mola
As etapas gerais para criar uma animação de mola para seu aplicativo são da seguinte forma:
- Adicionar a Biblioteca de Suporte Adicione a Biblioteca de Suporte ao projeto para usar as classes de animação de mola.
- Criar uma animação de mola:
A etapa principal é criar uma instância do
Classe
SpringAnimation
e define o movimento parâmetros de comportamento. - (Opcional) Registrar listeners:
Registrar listeners para observar animações e mudanças no ciclo de vida da animação
atualizações de valor.
Observação: o listener de atualização deve ser registrados somente se você precisar de atualização por frame no valor da animação. mudanças. Um listener de atualização impede que a animação em uma linha de execução separada.
- Remover listeners(opcional): Remova os listeners que não estão mais em uso.
- Defina um valor inicial(opcional): Personalizar o valor inicial da animação.
- Definir um intervalo de valores(opcional): Defina o intervalo de valores da animação para restringir os valores dentro dos intervalos mínimo e máximo.
- (Opcional) Definir a velocidade inicial: Defina a velocidade inicial da animação.
- (Opcional) Defina as propriedades da mola: Defina a proporção de amortecimento e a rigidez na mola.
- (Opcional) Criar uma mola personalizada: Crie uma mola personalizada caso não pretenda usar a mola padrão ou se quer usar uma mola comum na animação.
- Iniciar animação: Inicie a animação de mola.
- (Opcional) Cancelar animação: Cancelar a animação caso o usuário saia abruptamente do app ou da visualização se torna invisível.
As seções a seguir discutem as etapas gerais da criação de uma mola animação em detalhes.
Adicionar a Biblioteca de Suporte
Para usar a Biblioteca de Suporte baseada em física, você precisa adicioná-la ao seu projeto da seguinte forma:
- Abra o arquivo
build.gradle
relativo ao módulo do seu app. Adicione a Biblioteca de Suporte à seção
dependencies
.Groovy
dependencies { def dynamicanimation_version = '1.0.0' implementation "androidx.dynamicanimation:dynamicanimation:$dynamicanimation_version" }
Kotlin
dependencies { val dynamicanimation_version = "1.0.0" implementation("androidx.dynamicanimation:dynamicanimation:$dynamicanimation_version") }
Para visualizar as versões atuais desta biblioteca, consulte as informações sobre DynamicAnimation na página de versões.
Criar uma animação de mola
A classe SpringAnimation
permite criar
uma animação de mola para um objeto. Para criar uma animação de mola, você precisa
crie uma instância do SpringAnimation
classe e fornecem um objeto, a propriedade de um objeto que você deseja animar e um
a posição final opcional da mola, em que você quer que a animação descanse.
Observação:ao criar uma animação de mola, o elemento final a posição da mola é opcional. No entanto, ela precisa ser definida. antes de iniciar a animação.
Kotlin
val springAnim = findViewById<View>(R.id.imageView).let { img -> // Setting up a spring animation to animate the view’s translationY property with the final // spring position at 0. SpringAnimation(img, DynamicAnimation.TRANSLATION_Y, 0f) }
Java
final View img = findViewById(R.id.imageView); // Setting up a spring animation to animate the view’s translationY property with the final // spring position at 0. final SpringAnimation springAnim = new SpringAnimation(img, DynamicAnimation.TRANSLATION_Y, 0);
A animação de mola pode animar visualizações na tela alterando o propriedades reais nos objetos de visualização. As seguintes visualizações estão disponíveis no no sistema:
ALPHA
: Representa a transparência Alfa na visualização. O valor é 1 (opaco) por padrão, sendo que o valor 0 representa transparência total (não visível).TRANSLATION_X
,TRANSLATION_Y
eTRANSLATION_Z
: esses controlam onde a visualização está localizada como um delta a partir da esquerda coordenadas, coordenadas superiores e elevação, que são definidas pelo layout contêiner do Docker.TRANSLATION_X
descreve a coordenada esquerda.TRANSLATION_Y
descreve a coordenada superior.TRANSLATION_Z
descreve a profundidade da visualização em relação à elevação.
ROTATION
,ROTATION_X
eROTATION_Y
: esses controlam a rotação em 2D (propriedaderotation
) e 3D ao redor do ponto de rotação.SCROLL_X
eSCROLL_Y
: esses indicam o deslocamento de rolagem da origem esquerda e da borda superior em pixels. Ele também indica a posição em termos de quanto a página rolou.SCALE_X
eSCALE_Y
: esses controlam o escalonamento 2D de uma visualização em torno de seu ponto de rotação.X
,Y
eZ
: são recursos básicos propriedades utilitárias para descrever o local final da visualização na contêiner do Docker.X
é a soma dos o valor esquerdo eTRANSLATION_X
.Y
é a soma dos maior valor eTRANSLATION_Y
.Z
é a soma dos valor da elevação eTRANSLATION_Z
.
Registrar listeners
A classe DynamicAnimation
fornece dois
listeners: OnAnimationUpdateListener
e OnAnimationEndListener
.
Esses listeners ouvem as atualizações na animação, como quando há uma
mudança no valor da animação e quando ela chega ao fim.
OnAnimationUpdateListener
Quando quiser animar várias visualizações para criar uma animação encadeada,
podem configurar OnAnimationUpdateListener
receber uma chamada de retorno sempre que houver uma mudança no atributo
. O callback notifica a outra visualização para atualizar a posição da mola.
com base na alteração incorrida na propriedade da visualização atual. Para registrar o
listener, siga estas etapas:
-
Chamar
addUpdateListener()
e anexar o listener à animação.Observação:é necessário registrar a atualização ao listener antes do início da animação. No entanto, o listener de atualização deve ser registrados somente se você precisar de atualização por frame no valor da animação. mudanças. Um listener de atualização impede que a animação em uma linha de execução separada.
-
Substituir o
onAnimationUpdate()
para notificar o autor da chamada sobre a alteração no objeto atual. A o exemplo de código a seguir ilustra o uso geral deOnAnimationUpdateListener
:
Kotlin
// Setting up a spring animation to animate the view1 and view2 translationX and translationY properties val (anim1X, anim1Y) = findViewById<View>(R.id.view1).let { view1 -> SpringAnimation(view1, DynamicAnimation.TRANSLATION_X) to SpringAnimation(view1, DynamicAnimation.TRANSLATION_Y) } val (anim2X, anim2Y) = findViewById<View>(R.id.view2).let { view2 -> SpringAnimation(view2, DynamicAnimation.TRANSLATION_X) to SpringAnimation(view2, DynamicAnimation.TRANSLATION_Y) } // Registering the update listener anim1X.addUpdateListener { _, value, _ -> // Overriding the method to notify view2 about the change in the view1’s property. anim2X.animateToFinalPosition(value) } anim1Y.addUpdateListener { _, value, _ -> anim2Y.animateToFinalPosition(value) }
Java
// Creating two views to demonstrate the registration of the update listener. final View view1 = findViewById(R.id.view1); final View view2 = findViewById(R.id.view2); // Setting up a spring animation to animate the view1 and view2 translationX and translationY properties final SpringAnimation anim1X = new SpringAnimation(view1, DynamicAnimation.TRANSLATION_X); final SpringAnimation anim1Y = new SpringAnimation(view1, DynamicAnimation.TRANSLATION_Y); final SpringAnimation anim2X = new SpringAnimation(view2, DynamicAnimation.TRANSLATION_X); final SpringAnimation anim2Y = new SpringAnimation(view2, DynamicAnimation.TRANSLATION_Y); // Registering the update listener anim1X.addUpdateListener(new DynamicAnimation.OnAnimationUpdateListener() { // Overriding the method to notify view2 about the change in the view1’s property. @Override public void onAnimationUpdate(DynamicAnimation dynamicAnimation, float value, float velocity) { anim2X.animateToFinalPosition(value); } }); anim1Y.addUpdateListener(new DynamicAnimation.OnAnimationUpdateListener() { @Override public void onAnimationUpdate(DynamicAnimation dynamicAnimation, float value, float velocity) { anim2Y.animateToFinalPosition(value); } });
OnAnimationEndListener
OnAnimationEndListener
notifica o final de uma animação. É possível configurar o listener para receber
sempre que a animação atingir o equilíbrio ou for cancelada. Para
registrar o listener, siga estas etapas:
-
Chamar
addEndListener()
e anexar o listener à animação. -
Substituir
onAnimationEnd()
para receber uma notificação sempre que uma animação atingir o equilíbrio ou for cancelado.
Remover listeners
Para parar de receber callbacks de atualização de animação e callbacks de fim de animação,
ligar para removeUpdateListener()
e removeEndListener()
, respectivamente.
Definir o valor inicial da animação
Para definir o valor inicial da animação, chame o método
setStartValue()
e passar o valor inicial da animação. Se você não definir o
valor inicial, a animação usa o valor atual da propriedade do objeto
como o valor inicial.
Definir intervalo de valores de animação
Você pode definir os valores mínimo e máximo da animação quando quiser restringir o valor da propriedade a um determinado intervalo. Isso também ajuda a controlar intervalo caso você anime propriedades que tenham um intervalo intrínseco, como alfa (de 0 a 1).
-
Para definir o valor mínimo, chame o método
setMinValue()
e passar o valor mínimo da propriedade. -
Para definir o valor máximo, chame o método
setMaxValue()
e passar o valor máximo da propriedade.
Ambos os métodos retornam a animação para a qual o valor está sendo definido.
Observação: se você tiver definido o valor inicial e definiu um intervalo de valores de animação, verifique se o valor inicial está dentro do intervalo de valores mínimo e máximo.
Definir a velocidade inicial
A velocidade inicial define a velocidade em que a propriedade da animação muda no início da animação. A velocidade inicial padrão é definida como zero. pixels por segundo. É possível definir a velocidade com a velocidade do toque ou usando um valor fixo como velocidade inicial. Se você escolher têm um valor fixo, recomendamos definir o valor em dp por segundo e depois a converter em pixels por segundo. Definir o valor em dp por segundo permite que a velocidade seja independente da densidade e dos formatos. Para mais informações sobre como converter valor em pixels por segundo, consulte o Converter dp por segundo em pixels por segundo nesta seção.
Para definir a velocidade, chame o método
setStartVelocity()
e passar a velocidade em pixels por segundo. O método retorna o
objeto de força elástica em que a velocidade é definida.
Observação: use o
GestureDetector.OnGestureListener
ou a
Métodos da classe VelocityTracker
para recuperar e calcular
a velocidade dos gestos de toque.
Kotlin
findViewById<View>(R.id.imageView).also { img -> SpringAnimation(img, DynamicAnimation.TRANSLATION_Y).apply { … // Compute velocity in the unit pixel/second vt.computeCurrentVelocity(1000) val velocity = vt.yVelocity setStartVelocity(velocity) } }
Java
final View img = findViewById(R.id.imageView); final SpringAnimation anim = new SpringAnimation(img, DynamicAnimation.TRANSLATION_Y); … // Compute velocity in the unit pixel/second vt.computeCurrentVelocity(1000); float velocity = vt.getYVelocity(); anim.setStartVelocity(velocity);
Converter dp por segundo em pixels por segundo
A velocidade de uma mola precisa ser definida em pixels por segundo. Se você optar por fornecer um
valor fixo como o início da velocidade, forneça o valor em dp por segundo
e depois a converter em pixels por segundo. Para a conversão, use o método
applyDimension()
da classe TypedValue
. Consulte a
exemplo de código a seguir:
Kotlin
val pixelPerSecond: Float = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpPerSecond, resources.displayMetrics)
Java
float pixelPerSecond = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpPerSecond, getResources().getDisplayMetrics());
Definir propriedades da mola
A classe SpringForce
define o getter.
e os métodos setter para cada uma das propriedades da mola, como o amortecimento
proporção e rigidez. Para definir as propriedades da mola, é importante
recuperar o objeto de força elástica ou criar uma força elástica personalizada sobre a qual
você pode definir as propriedades. Para mais informações sobre como criar um
força elástica, consulte a
Como criar uma força elástica personalizada
nesta seção.
Dica:ao usar os métodos setter, você pode Criar uma cadeia de métodos, já que todos os métodos setter retornam a força elástica objeto.
Proporção de amortecimento
A proporção de amortecimento descreve uma redução gradual na oscilação da mola. De usando a proporção de amortecimento, é possível definir a velocidade de declínio das oscilações de uma rejeição para outra. Há quatro maneiras diferentes de abafar primavera:
- O amortecimento excessivo ocorre quando a proporção é maior que um. Permite o objeto retorne suavemente à posição de repouso.
- O amortecimento crítico ocorre quando a proporção é igual a um. Permite o objeto retorne à posição de repouso no menor tempo possível.
- O amortecimento insuficiente ocorre quando a proporção é inferior a um. Permite ultrapassar a posição de repouso do objeto várias vezes e, em seguida, alcance gradualmente a posição de repouso.
- O não amortecimento ocorre quando a proporção é igual a zero. Ela permite que oscilar para sempre.
Para adicionar a proporção de amortecimento à mola, siga estas etapas:
-
Chamar
getSpring()
para recuperar a mola e adicionar a proporção de amortecimento. -
Chamar
setDampingRatio()
e transmita a proporção de amortecimento que você quer adicionar à mola. A retorna o objeto de força elástica em que a proporção de amortecimento está definida.Observação:a proporção de amortecimento precisa ser um valor. e não negativo. Se você definir a proporção de amortecimento como zero, a mola nunca chegar à posição de repouso. Em outras palavras, ele oscilará para sempre.
As seguintes constantes de proporção de amortecimento estão disponíveis no sistema:
DAMPING_RATIO_HIGH_BOUNCY
DAMPING_RATIO_MEDIUM_BOUNCY
DAMPING_RATIO_LOW_BOUNCY
DAMPING_RATIO_NO_BOUNCY
Figura 2: oscilação alta
Figura 3: oscilação médio
Figura 4: oscilação baixa
Figura 5: sem oscilação
A proporção de amortecimento padrão é definida como DAMPING_RATIO_MEDIUM_BOUNCY
.
Kotlin
findViewById<View>(R.id.imageView).also { img -> SpringAnimation(img, DynamicAnimation.TRANSLATION_Y).apply { … // Setting the damping ratio to create a low bouncing effect. spring.dampingRatio = SpringForce.DAMPING_RATIO_LOW_BOUNCY … } }
Java
final View img = findViewById(R.id.imageView); final SpringAnimation anim = new SpringAnimation(img, DynamicAnimation.TRANSLATION_Y); … // Setting the damping ratio to create a low bouncing effect. anim.getSpring().setDampingRatio(SpringForce.DAMPING_RATIO_LOW_BOUNCY); …
Rigidez
A rigidez define a constante da mola, que mede a intensidade nascente. Uma mola rígida aplica mais força ao objeto anexado quando a mola não está na posição de repouso. Para adicionar rigidez à mola, siga estas etapas:
-
Chamar
getSpring()
para recuperar a mola e adicionar rigidez. -
Chamar
setStiffness()
e transmita o valor de rigidez que você quer adicionar à mola. A retorna o objeto de força elástica em que a rigidez está definida.Observação: a rigidez deve ser um número positivo.
As seguintes constantes de rigidez estão disponíveis no sistema:
Figura 6: rigidez alta
Figura 7: rigidez média
Figura 8: rigidez baixa
Figura 9: rigidez muito baixa
A rigidez padrão é definida como STIFFNESS_MEDIUM
.
Kotlin
findViewById<View>(R.id.imageView).also { img -> SpringAnimation(img, DynamicAnimation.TRANSLATION_Y).apply { … // Setting the spring with a low stiffness. spring.stiffness = SpringForce.STIFFNESS_LOW … } }
Java
final View img = findViewById(R.id.imageView); final SpringAnimation anim = new SpringAnimation(img, DynamicAnimation.TRANSLATION_Y); … // Setting the spring with a low stiffness. anim.getSpring().setStiffness(SpringForce.STIFFNESS_LOW); …
Criar uma força elástica personalizada
É possível criar uma força elástica personalizada como alternativa ao uso do valor padrão força elástica. A força elástica personalizada permite compartilhar a mesma força elástica instância em várias animações de mola. Depois de criar a mola é possível definir propriedades como a proporção de amortecimento e a rigidez.
-
Crie um objeto
SpringForce
.SpringForce force = new SpringForce();
-
Atribua as propriedades chamando os respectivos métodos. Você também pode
criar uma cadeia de métodos.
force.setDampingRatio(DAMPING_RATIO_LOW_BOUNCY).setStiffness(STIFFNESS_LOW);
-
Chamar
setSpring()
para definir a mola da animação.setSpring(force);
Iniciar animação
Há duas maneiras de iniciar uma animação de mola: chamando o método
start()
ou chamando o
animateToFinalPosition()
. Os dois métodos precisam ser chamados na linha de execução principal.
animateToFinalPosition()
executa duas tarefas:
- Definir a posição final da mola.
- Iniciar a animação, se ela não tiver sido iniciada.
Como o método atualiza a posição final da mola e inicia o
se necessário, chame esse método a qualquer momento para mudar o curso
de uma animação. Por exemplo, em uma animação de mola encadeada,
de uma visualização depende de outra. Para esse tipo de animação,
o uso do
animateToFinalPosition()
. Ao usar esse método em uma animação de mola encadeada, não é necessário
se preocupar se a animação que você quer atualizar em seguida está em execução.
A Figura 10 ilustra uma animação de mola encadeada, em que a animação de uma visualização depende de outra.
![Demonstração de mola encadeada](https://developer.android.com/static/images/guide/topics/graphics/spring_chain.gif?authuser=9&hl=pt)
Para usar o animateToFinalPosition()
, chame o método
animateToFinalPosition()
e passar a posição de repouso da mola. Também é possível definir o restante
a posição da mola chamando
setFinalPosition()
.
O método start()
faz
não definir o valor da propriedade para o valor inicial imediatamente. A propriedade
muda a cada pulso da animação, o que acontece antes da passagem do desenho.
Como resultado, as alterações são refletidas no frame seguinte, como se
os valores são definidos imediatamente.
Kotlin
findViewById<View>(R.id.imageView).also { img -> SpringAnimation(img, DynamicAnimation.TRANSLATION_Y).apply { … // Starting the animation start() … } }
Java
final View img = findViewById(R.id.imageView); final SpringAnimation anim = new SpringAnimation(img, DynamicAnimation.TRANSLATION_Y); … // Starting the animation anim.start(); …
Cancelar animação
Você pode cancelar ou pular para o final da animação. Uma situação ideal em que você precisa cancelar ou pular para o final da alteração é quando um usuário exige que a animação seja encerrada imediatamente. Isso é principalmente quando um usuário sai de um app de forma abrupta ou a visualização se torna invisível.
Há dois métodos que você pode usar para encerrar a animação.
Método cancel()
encerra a animação no valor em que se encontra. A
Método skipToEnd()
pula a animação para o valor final e a encerra.
Antes de encerrar a animação, é importante verificar primeiro
o estado da mola. Se o estado não for amortecido, a animação nunca alcançará
a posição de repouso.
Para verificar o estado da mola, chame o método
canSkipToEnd()
. Se
a mola for amortecida, o método retornará true
. Caso contrário,
false
.
Depois de saber o estado da mola, você pode encerrar uma animação
usando
método skipToEnd()
ou o
cancel()
. A
Método cancel()
precisa ser chamado apenas na linha de execução principal.
Observação:em geral, o
Causas do método skipToEnd()
um salto visual.