Mover visualização usando animação com rolagem

A animação de rolagem usa uma força de atrito proporcional à velocidade do objeto. Use-a para animar uma propriedade de um objeto caso você queira que a animação termine gradualmente. Ela tem um momentum inicial, que é recebido principalmente a partir da velocidade do gesto, e desacelera gradualmente. A animação termina quando a velocidade é baixa o suficiente para que não haja mudanças visíveis na tela do dispositivo.

Figura 1. Animação de rolagem.

Para saber mais sobre temas relacionados, leia os seguintes guias:

Adicionar a Biblioteca de Suporte

Para usar a Biblioteca de Suporte baseada em física, é preciso adicioná-la ao seu projeto da seguinte forma:

  1. Abra o arquivo build.gradle para o módulo do seu app.
  2. Adicione a Biblioteca de Suporte à seção dependencies.
          dependencies {
              implementation 'com.android.support:support-dynamic-animation:28.0.0'
          }
          

Criar uma animação de rolagem

A classe FlingAnimation permite criar uma animação de rolagem para um objeto. Para criar esse tipo de animação, crie uma instância da classe FlingAnimation e forneça um objeto e a propriedade dele que você quer animar.

Kotlin

    val fling = FlingAnimation(view, DynamicAnimation.SCROLL_X)
    

Java

    FlingAnimation fling = new FlingAnimation(view, DynamicAnimation.SCROLL_X);
    

Definir a velocidade

A velocidade inicial define a velocidade em que uma propriedade da animação muda no início dela. A velocidade inicial padrão é definida como zero pixel por segundo. Portanto, é necessário definir uma velocidade inicial para garantir que a animação não termine imediatamente.

Você pode usar um valor fixo como a velocidade inicial ou baseá-lo na velocidade de um gesto de toque. Se você preferir informar um valor fixo, defina-o em dp por segundo e, em seguida, converta-o em pixels por segundo. A definição do valor em dp por segundo permite que a velocidade seja independente da densidade e dos formatos do dispositivo. Para saber mais sobre como converter a velocidade inicial em pixels por segundo, consulte a seção Converter pd por segundo em pixels por segundo em Animação de rolagem.

Para definir a velocidade, chame o método setStartVelocity() e transmita a velocidade em pixels por segundo. O método retorna o objeto de rolagem em que a velocidade está definida.

Observação: use as classes GestureDetector.OnGestureListener e VelocityTracker para recuperar e calcular a velocidade dos gestos de toque, respectivamente.

Definir um intervalo de valores de animação

É possível definir os valores mínimo e máximo de animação para restringir o valor da propriedade a um determinado intervalo. Esse controle de intervalo é particularmente útil ao animar propriedades que têm um intervalo intrínseco, como alpha (de 0 a 1).

Observação: quando o valor de uma animação de rolagem atinge o valor mínimo ou máximo, a animação termina.

Para definir os valores mínimo e máximo, chame os métodos setMinValue() e setMaxValue(), respectivamente. Ambos os métodos retornam o objeto de animação para o qual você definiu o valor.

Definir o atrito

O método setFriction() permite mudar o atrito da animação. Ele define a rapidez com que a velocidade diminui em uma animação.

Observação: se você não definir o atrito no início da animação, ela usará o valor padrão 1.

O método retorna o objeto cuja animação usa o valor de atrito informado.

Amostra de código

O exemplo abaixo ilustra uma rolagem horizontal. A velocidade capturada do rastreador é velocityX, e os limites de rolagem são definidos como 0 e maxScroll. O atrito é definido como 1,1.

Kotlin

    FlingAnimation(view, DynamicAnimation.SCROLL_X).apply {
        setStartVelocity(-velocityX)
        setMinValue(0f)
        setMaxValue(maxScroll)
        friction = 1.1f
        start()
    }
    

Java

    FlingAnimation fling = new FlingAnimation(view, DynamicAnimation.SCROLL_X);
    fling.setStartVelocity(-velocityX)
            .setMinValue(0)
            .setMaxValue(maxScroll)
            .setFriction(1.1f)
            .start();
    

Definir a mudança mínima visível

Ao animar uma propriedade personalizada não definida em pixels, determine a mudança mínima do valor de animação visível para os usuários. Esse valor determina um limite razoável para encerrar a animação.

Não é necessário chamar esse método ao animar DynamicAnimation.ViewProperty, porque a mudança mínima visível deriva da propriedade. Por exemplo:

  • O valor padrão da mudança mínima visível é 1 pixel para propriedades de visualização, como TRANSLATION_X, TRANSLATION_Y, TRANSLATION_Z, SCROLL_X e SCROLL_Y.
  • Para animações que usam rotação, como ROTATION, ROTATION_X e ROTATION_Y, a mudança mínima visível é MIN_VISIBLE_CHANGE_ROTATION_DEGREES, ou 1/10 pixel.
  • Para animações que usam opacidade, a mudança mínima visível é MIN_VISIBLE_CHANGE_ALPHA, ou 1/256.

Para definir a mudança mínima visível de uma animação, chame o método setMinimumVisibleChange() e transmita uma das constantes visíveis mínimas ou um valor que você precisa calcular para uma propriedade personalizada. Para mais informações sobre como calcular esse valor, consulte a seção Calcular um valor de mudança mínima visível.

Kotlin

    anim.minimumVisibleChange = DynamicAnimation.MIN_VISIBLE_CHANGE_SCALE
    

Java

    anim.setMinimumVisibleChange(DynamicAnimation.MIN_VISIBLE_CHANGE_SCALE);
    

Observação: é preciso transmitir um valor somente ao animar uma propriedade personalizada não definida em pixels.

Calcular um valor de mudança mínima visível

Para calcular o valor de mudança mínima visível de uma propriedade personalizada, use esta fórmula:

Mudança mínima visível = Intervalo de valores da propriedade personalizada / Intervalo de animação em pixels

Por exemplo, a propriedade que você quer animar vai de 0 a 100. Isso corresponde a uma mudança de 200 pixels. De acordo com a fórmula, o valor da mudança mínima visível é 100 / 200, ou 0,5 pixel.