Geralmente, muitas das APIs de animação aceitam parâmetros para personalização de comportamentos.
Personalizar animações com o parâmetro AnimationSpec
A maioria das APIs de animação permite que os desenvolvedores personalizem as especificações de animação
usando um parâmetro AnimationSpec
opcional.
val alpha: Float by animateFloatAsState( targetValue = if (enabled) 1f else 0.5f, // Configure the animation duration and easing. animationSpec = tween(durationMillis = 300, easing = FastOutSlowInEasing), label = "alpha" )
Existem diferentes tipos de AnimationSpec
para criação de diferentes tipos de
animação.
Criar animação baseada em física usando spring
A spring
cria uma animação baseada em física entre os valores inicial e final. Ela
precisa de dois parâmetros: dampingRatio
e stiffness
.
dampingRatio
define o grau de mobilidade da spring. O valor padrão é
Spring.DampingRatioNoBouncy
.
Figura 1. Definir diferentes proporções de amortecimento da mola.
stiffness
define a velocidade de movimento da spring em direção ao valor final. O
valor padrão é Spring.StiffnessMedium
.
Figura 2. Definir rigidez de mola diferente
val value by animateFloatAsState( targetValue = 1f, animationSpec = spring( dampingRatio = Spring.DampingRatioHighBouncy, stiffness = Spring.StiffnessMedium ), label = "spring spec" )
A spring
pode processar interrupções de forma melhor que tipos de
AnimationSpec
baseados em duração, porque garante a continuidade da velocidade quando
o valor de destino muda entre animações. spring
é usada como o AnimationSpec padrão
por muitas APIs de animação, como animate*AsState
e
updateTransition
.
Por exemplo, se aplicarmos uma configuração spring
à animação a seguir, que é acionada pelo toque do usuário, ao interromper a animação enquanto ela avança, o uso de tween
não responde tão bem quanto usar spring
.
Figura 3. Definir especificações tween
e spring
para a animação e interromper a animação.
Animar entre os valores inicial e final com a curva de easing usando tween
tween
executa animações entre os valores inicial e final na
durationMillis
especificada, usando uma curva de easing. tween
é a abreviação da palavra "between" (entre) porque vai entre dois valores.
Você também pode especificar delayMillis
para adiar o início da animação.
val value by animateFloatAsState( targetValue = 1f, animationSpec = tween( durationMillis = 300, delayMillis = 50, easing = LinearOutSlowInEasing ), label = "tween delay" )
Consulte Easing para mais informações.
Animar valores específicos em determinados momentos com keyframes
keyframes
executam animações com base nos valores resumidos especificados em carimbos de data/hora
diferentes na duração da animação. O valor de animação
será interpolado entre dois valores keyframe a qualquer momento. O easing pode ser especificado
para qualquer um dos keyframes para determinar a curva de interpolação.
Especificar os valores como 0 ms e o tempo de duração é opcional. Caso esses valores não sejam especificados, o padrão será os valores inicial e final da animação, respectivamente.
val value by animateFloatAsState( targetValue = 1f, animationSpec = keyframes { durationMillis = 375 0.0f at 0 using LinearOutSlowInEasing // for 0-15 ms 0.2f at 15 using FastOutLinearInEasing // for 15-75 ms 0.4f at 75 // ms 0.4f at 225 // ms }, label = "keyframe" )
Repetir uma animação com repeatable
repeatable
executa uma animação baseada em duração (como tween
ou keyframes
)
repetidamente, até alcançar a contagem de iteração especificada. É possível transmitir o parâmetro
repeatMode
para especificar se a animação vai ser repetida
começando do início (RepeatMode.Restart
) ou do final
(RepeatMode.Reverse
).
val value by animateFloatAsState( targetValue = 1f, animationSpec = repeatable( iterations = 3, animation = tween(durationMillis = 300), repeatMode = RepeatMode.Reverse ), label = "repeatable spec" )
Repetir uma animação infinitamente com infiniteRepeatable
infiniteRepeatable
é semelhante a repeatable
, mas essa função se repete por uma quantidade infinita
de iterações.
val value by animateFloatAsState( targetValue = 1f, animationSpec = infiniteRepeatable( animation = tween(durationMillis = 300), repeatMode = RepeatMode.Reverse ), label = "infinite repeatable" )
Animações que usam infiniteRepeatable
não são executadas em testes que usam
ComposeTestRule
. O componente será
renderizado usando o valor inicial de cada valor de animação.
Ajustar imediatamente o valor final com snap
snap
é uma AnimationSpec
especial que muda imediatamente o valor para o
valor final. Você pode especificar delayMillis
para atrasar o início da
animação.
val value by animateFloatAsState( targetValue = 1f, animationSpec = snap(delayMillis = 50), label = "snap spec" )
Definir uma função de easing personalizada
As operações AnimationSpec
baseadas em duração (como tween
ou keyframes
) usam
Easing
para ajustar a fração da animação. Isso permite que o valor de animação
acelere e desacelere, em vez de se mover a uma taxa constante. Uma fração é um
valor entre 0 (início) e 1,0 (fim) indicando o ponto atual da
animação.
O easing é, na verdade, uma função que usa um valor de fração entre 0 e 1,0 e retorna um ponto flutuante. O valor retornado pode estar fora do limite para representar uma ultrapassagem ou uma redução. Um easing personalizado pode ser criado, como no código abaixo.
val CustomEasing = Easing { fraction -> fraction * fraction } @Composable fun EasingUsage() { val value by animateFloatAsState( targetValue = 1f, animationSpec = tween( durationMillis = 300, easing = CustomEasing ), label = "custom easing" ) // …… }
O Compose oferece várias funções Easing
integradas que abrangem a maioria dos casos de uso.
Consulte Speed - Material Design (link em inglês) para mais
informações sobre qual easing usar dependendo do cenário.
FastOutSlowInEasing
LinearOutSlowInEasing
FastOutLinearEasing
LinearEasing
CubicBezierEasing
- Veja mais
Animar tipos de dados personalizados convertendo-os em AnimationVector
e vice-versa
A maioria das APIs de animação do Compose oferece suporte a Float
, Color
, Dp
e outros tipos de dados
básicos como valores de animação por padrão, mas às vezes é necessário animar
outros tipos de dados, incluindo os personalizados. Durante a animação, qualquer valor de
animação é representado como um AnimationVector
. O valor é convertido em um
AnimationVector
, e vice-versa, por um TwoWayConverter
correspondente para que
o sistema de animação principal possa processá-lo de maneira uniforme. Por exemplo, uma Int
é
representada como um AnimationVector1D
contendo um único valor flutuante.
Para TwoWayConverter
, o Int
é assim:
val IntToVector: TwoWayConverter<Int, AnimationVector1D> = TwoWayConverter({ AnimationVector1D(it.toFloat()) }, { it.value.toInt() })
A Color
é essencialmente um conjunto de quatro valores: vermelho, verde, azul e alfa. A
Color
é convertida em um AnimationVector4D
contendo quatro valores flutuantes. Dessa
forma, cada tipo de dados usado nas animações é convertido em
AnimationVector1D
, AnimationVector2D
, AnimationVector3D
ou
AnimationVector4D
, dependendo da dimensionalidade. Isso permite que
diferentes componentes do objeto sejam animados de forma independente, com
rastreamentos de velocidade próprios. Os conversores integrados para tipos de dados básicos podem ser acessados
usando conversores como Color.VectorConverter
ou Dp.VectorConverter
.
Caso queira adicionar compatibilidade com um novo tipo de dados como um valor de animação,
crie seu próprio TwoWayConverter
e forneça-o à API. Por exemplo,
é possível usar animateValueAsState
para animar o tipo de dados personalizado da seguinte forma:
data class MySize(val width: Dp, val height: Dp) @Composable fun MyAnimation(targetSize: MySize) { val animSize: MySize by animateValueAsState( targetSize, TwoWayConverter( convertToVector = { size: MySize -> // Extract a float value from each of the `Dp` fields. AnimationVector2D(size.width.value, size.height.value) }, convertFromVector = { vector: AnimationVector2D -> MySize(vector.v1.dp, vector.v2.dp) } ), label = "size" ) }
A lista a seguir inclui algumas VectorConverter
s integradas:
Color.VectorConverter
Dp.VectorConverter
Offset.VectorConverter
Int.VectorConverter
Float.VectorConverter
IntSize.VectorConverter
Recomendados para você
- Observação: o texto do link aparece quando o JavaScript está desativado.
- Animações com base no valor
- Desenvolvimento de código iterativo {:#iterative-code-dev }
- Animações no Compose