Molte API di animazione accettano comunemente parametri per personalizzare il loro comportamento.
Personalizzare le animazioni con il parametro AnimationSpec
La maggior parte delle API di animazione consente agli sviluppatori di personalizzare le specifiche di animazione tramite un
parametro AnimationSpec
facoltativo.
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" )
Esistono diversi tipi di AnimationSpec
per creare diversi tipi di animazioni.
Creare animazioni basate sulla fisica con spring
spring
crea un'animazione basata sulla fisica tra i valori iniziale e finale. Richiede 2 parametri: dampingRatio
e stiffness
.
dampingRatio
definisce l'elasticità della molla. Il valore predefinito è
Spring.DampingRatioNoBouncy
.
Figura 1. Impostazione di diversi rapporti di smorzamento delle molle.
stiffness
definisce la velocità con cui la molla deve muoversi verso il valore finale. Il valore predefinito è Spring.StiffnessMedium
.
Figura 2. Impostazione di una rigidità della molla diversa
val value by animateFloatAsState( targetValue = 1f, animationSpec = spring( dampingRatio = Spring.DampingRatioHighBouncy, stiffness = Spring.StiffnessMedium ), label = "spring spec" )
spring
può gestire le interruzioni in modo più agevole rispetto ai tipi spring
basati sulla durata perché garantisce la continuità della velocità quando il valore target cambia durante le animazioni.AnimationSpec
spring
viene utilizzato come AnimationSpec predefinito da molte API di animazione, come animate*AsState
e
updateTransition
.
Ad esempio, se applichiamo una configurazione spring
alla seguente animazione basata sul tocco dell'utente, quando interrompi l'animazione durante il suo avanzamento, puoi notare che l'utilizzo di tween
non risponde in modo fluido come l'utilizzo di spring
.
Figura 3. Impostazione delle specifiche tween
rispetto a spring
per l'animazione e interruzione.
Applica un'animazione tra i valori iniziale e finale con una curva di easing con tween
tween
anima i valori iniziale e finale in base al valore durationMillis
specificato utilizzando una curva di easing. tween
è l'abbreviazione della parola tra, in quanto si trova tra due valori.
Puoi anche specificare delayMillis
per posticipare l'inizio dell'animazione.
val value by animateFloatAsState( targetValue = 1f, animationSpec = tween( durationMillis = 300, delayMillis = 50, easing = LinearOutSlowInEasing ), label = "tween delay" )
Per ulteriori informazioni, consulta la sezione Effetti di transizione.
Esegui l'animazione fino a valori specifici in determinati momenti con keyframes
keyframes
si anima in base ai valori dello snapshot specificati in diversi
timestamp durante la durata dell'animazione. In qualsiasi momento, il valore
dell'animazione verrà interpolato tra due valori di fotogramma chiave. Per ciascuno di questikeyframe, puoi specificare la funzionalità Easing per determinare la curva di interpolazione.
È facoltativo specificare i valori a 0 ms e al momento della durata. Se non li specifichi, per impostazione predefinita vengono utilizzati i valori iniziale e finale dell'animazione.
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" )
Ripeti un'animazione con repeatable
repeatable
esegue un'animazione basata sulla durata (ad esempio tween
o keyframes
)
ripetutamente fino a raggiungere il numero di iterazioni specificato. Puoi passare il parametro repeatMode
per specificare se l'animazione deve ripetersi iniziando dall'inizio (RepeatMode.Restart
) o dalla fine (RepeatMode.Reverse
).
val value by animateFloatAsState( targetValue = 1f, animationSpec = repeatable( iterations = 3, animation = tween(durationMillis = 300), repeatMode = RepeatMode.Reverse ), label = "repeatable spec" )
Ripeti un'animazione all'infinito con infiniteRepeatable
infiniteRepeatable
è simile a repeatable
, ma si ripete per un numero infinito di iterazioni.
val value by animateFloatAsState( targetValue = 1f, animationSpec = infiniteRepeatable( animation = tween(durationMillis = 300), repeatMode = RepeatMode.Reverse ), label = "infinite repeatable" )
Nei test che utilizzano
ComposeTestRule
,
le animazioni che utilizzano infiniteRepeatable
non vengono eseguite. Il componente verrà visualizzato utilizzando il valore iniziale di ogni valore animato.
Passa immediatamente al valore di fine con snap
snap
è un AnimationSpec
speciale che passa immediatamente il valore al valore finale. Puoi specificare delayMillis
per ritardare l'inizio dell'animazione.
val value by animateFloatAsState( targetValue = 1f, animationSpec = snap(delayMillis = 50), label = "snap spec" )
Impostare una funzione di attenuazione personalizzata
Le operazioni AnimationSpec
basate sulla durata (ad esempio tween
o keyframes
) utilizzano
Easing
per regolare la frazione di un'animazione. In questo modo, il valore animato può accelerare e rallentare, anziché muoversi a una velocità costante. La frazione è un valore compreso tra 0 (inizio) e 1,0 (fine) che indica il punto corrente dell'animazione.
La funzione di transizione è in realtà una funzione che prende un valore frazionario compreso tra 0 e 1,0 e restituisce un valore float. Il valore restituito può essere esterno al confine per rappresentare un overshoot o un undershoot. È possibile creare un'animazione personalizzata come il codice riportato di seguito.
val CustomEasing = Easing { fraction -> fraction * fraction } @Composable fun EasingUsage() { val value by animateFloatAsState( targetValue = 1f, animationSpec = tween( durationMillis = 300, easing = CustomEasing ), label = "custom easing" ) // …… }
Compose fornisce diverse funzioni Easing
integrate che coprono la maggior parte dei casi d'uso.
Per ulteriori informazioni su che cosa si intende per facilità d'uso a seconda dello scenario, consulta Velocità - Material Design.
FastOutSlowInEasing
LinearOutSlowInEasing
FastOutLinearEasing
LinearEasing
CubicBezierEasing
- Scopri di più
Anima i tipi di dati personalizzati convertendoli in AnimationVector
e da AnimationVector
Per impostazione predefinita, la maggior parte delle API di animazione di Compose supporta Float
, Color
, Dp
e altri tipi di dati di base come valori di animazione, ma a volte è necessario animare altri tipi di dati, inclusi quelli personalizzati. Durante l'animazione, qualsiasi valore animato è rappresentato come AnimationVector
. Il valore viene convertito in un
AnimationVector
e viceversa da un TwoWayConverter
corrispondente in modo che
il sistema di animazione di base possa gestirli in modo uniforme. Ad esempio, un Int
viene rappresentato come un AnimationVector1D
contenente un singolo valore in virgola mobile.
TwoWayConverter
per Int
ha questo aspetto:
val IntToVector: TwoWayConverter<Int, AnimationVector1D> = TwoWayConverter({ AnimationVector1D(it.toFloat()) }, { it.value.toInt() })
Color
è essenzialmente un insieme di 4 valori, rosso, verde, blu e alfa, quindi
Color
viene convertito in un AnimationVector4D
contenente 4 valori float. In questo modo, ogni tipo di dato utilizzato nelle animazioni viene convertito in AnimationVector1D
, AnimationVector2D
, AnimationVector3D
o AnimationVector4D
a seconda della sua dimensionalità. In questo modo, i diversi componenti dell'oggetto possono essere animati in modo indipendente, ciascuno con il proprio monitoraggio della velocità. È possibile accedere ai convertitori integrati per i tipi di dati di base utilizzando convertitori come Color.VectorConverter
o Dp.VectorConverter
.
Quando vuoi aggiungere il supporto di un nuovo tipo di dati come valore animato, puoi creare il tuo TwoWayConverter
e fornirlo all'API. Ad esempio, puoi utilizzare animateValueAsState
per animare il tipo di dati personalizzati come segue:
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" ) }
Il seguente elenco include alcuni VectorConverter
integrati:
Color.VectorConverter
Dp.VectorConverter
Offset.VectorConverter
Int.VectorConverter
Float.VectorConverter
IntSize.VectorConverter
Consigliati per te
- Nota: il testo del link viene visualizzato quando JavaScript è disattivato
- Animazioni basate sul valore
- Sviluppo di codice iterativo {:#iterative-code-dev }
- Animazioni in Compose