Wiele interfejsów API animacji zwykle akceptuje parametry umożliwiające dostosowywanie ich działania.
Dostosowywanie animacji za pomocą parametru AnimationSpec
Większość interfejsów API do animacji umożliwia deweloperom dostosowywanie specyfikacji animacji za pomocą opcjonalnego parametru AnimationSpec
.
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" )
Do tworzenia różnych rodzajów animacji służą różne rodzaje AnimationSpec
.
Tworzenie animacji opartej na fizyce za pomocą spring
spring
tworzy animację opartą na fizyce między wartościami początkowymi i końcowymi. Przyjmuje 2 parametry: dampingRatio
i stiffness
.
dampingRatio
określa, jak sprężystość ma być duża. Wartością domyślną jest Spring.DampingRatioNoBouncy
.
Rysunek 1. Ustawianie różnych współczynników tłumienia sprężyny.
stiffness
określa, jak szybko sprężyna ma się zbliżać do wartości końcowej. Wartością domyślną jest Spring.StiffnessMedium
.
Rysunek 2. Ustawianie różnych stopni twardości sprężyny
val value by animateFloatAsState( targetValue = 1f, animationSpec = spring( dampingRatio = Spring.DampingRatioHighBouncy, stiffness = Spring.StiffnessMedium ), label = "spring spec" )
Typ spring
może płynniej obsługiwać przerwy niż typy AnimationSpec
oparte na czasie trwania, ponieważ gwarantuje ciągłość prędkości podczas zmiany wartości docelowej w animacjach. spring
jest używana jako domyślna specyfikacja animacji przez wiele interfejsów API animacji, takich jak animate*AsState
i updateTransition
.
Jeśli na przykład zastosujemy konfigurację spring
do poniższej animacji, która jest uruchamiana przez dotyk użytkownika, i przerwiemy animację w trakcie jej odtwarzania, zauważymy, że użycie tween
nie powoduje tak płynnej reakcji jak użycie spring
.
Rysunek 3. Ustawianie specyfikacji tween
lub spring
dla animacji i przerywanie jej.
Animacja między wartościami początkową i końcową z krzywą wykładniczą z parametrem tween
tween
animuje przejście między wartościami początkową i końcową w określonym zakresie durationMillis
za pomocą wygładzonej krzywej. tween
to skrót od słowa „between” (pomiędzy), ponieważ pomiędzy 2 wartościami.
Możesz też ustawić wartość delayMillis
, aby opóźnić rozpoczęcie animacji.
val value by animateFloatAsState( targetValue = 1f, animationSpec = tween( durationMillis = 300, delayMillis = 50, easing = LinearOutSlowInEasing ), label = "tween delay" )
Więcej informacji znajdziesz w sekcji Zwolnienie.
Animacja do określonych wartości w określonym czasie za pomocą funkcji keyframes
keyframes
animuje się na podstawie wartości migawkowych określonych w różnych punktach czasowych w czasie trwania animacji. W każdej chwili wartość animacji będzie interpolowana między 2 wartościami klatki kluczowej. W przypadku każdego z tych klawiszy płynności możesz określić krzywą interpolacji.
Wartości w 0 ms i w czasie trwania są opcjonalne. Jeśli nie określisz tych wartości, zostaną one domyślnie ustawione na wartości początkową i końcową animacji.
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" )
Powtarzanie animacji za pomocą repeatable
repeatable
uruchamia animację opartą na czasie trwania (np. tween
lub keyframes
) wielokrotnie, aż osiągnie określoną liczbę iteracji. Możesz przekazać parametr repeatMode
, aby określić, czy animacja ma się powtarzać, zaczynając od początku (RepeatMode.Restart
) czy od końca (RepeatMode.Reverse
).
val value by animateFloatAsState( targetValue = 1f, animationSpec = repeatable( iterations = 3, animation = tween(durationMillis = 300), repeatMode = RepeatMode.Reverse ), label = "repeatable spec" )
Powtarzanie animacji w nieskończoność za pomocą infiniteRepeatable
Funkcja infiniteRepeatable
jest podobna do funkcji repeatable
, ale powtarza się w nieskończonej liczbie iteracji.
val value by animateFloatAsState( targetValue = 1f, animationSpec = infiniteRepeatable( animation = tween(durationMillis = 300), repeatMode = RepeatMode.Reverse ), label = "infinite repeatable" )
W testach korzystających z ComposeTestRule
animacje korzystające z infiniteRepeatable
nie są uruchamiane. Składnik zostanie wyrenderowany, używając wartości początkowej każdej animowanej wartości.
Natychmiastowe zablokowanie wartości końcowej za pomocą snap
snap
to specjalny AnimationSpec
, który natychmiast przełącza wartość na wartość końcową. Aby opóźnić rozpoczęcie animacji, możesz ustawić wartość delayMillis
.
val value by animateFloatAsState( targetValue = 1f, animationSpec = snap(delayMillis = 50), label = "snap spec" )
Ustawianie niestandardowej funkcji wygładzania
Operacje AnimationSpec
oparte na czasie trwania (takie jak tween
lub keyframes
) używają funkcji Easing
do dostosowywania ułamka animacji. Dzięki temu wartość animacji może przyspieszać i zwalniać, zamiast poruszać się z równą prędkością. Ułamek to wartość z zakresu od 0 (początek) do 1,0 (koniec), która wskazuje bieżący punkt animacji.
Spłaszczenie jest w istocie funkcją, która przyjmuje wartość ułamkową z zakresu od 0 do 1,0 i zwraca liczbę zmiennoprzecinkową. Zwrócona wartość może wykraczać poza granice, co oznacza przekroczenie lub niedociągnięcie celu. Niestandardowe wygładzanie możesz utworzyć za pomocą kodu poniżej.
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 udostępnia kilka wbudowanych funkcji Easing
, które obejmują większość przypadków użycia.
Więcej informacji o tym, jaką metodę wygaszania należy zastosować w danym scenariuszu, znajdziesz w artykule Szybkość – Material Design.
FastOutSlowInEasing
LinearOutSlowInEasing
FastOutLinearEasing
LinearEasing
CubicBezierEasing
- Pokaż więcej
Animowanie niestandardowych typów danych przez konwertowanie z poziomu i na AnimationVector
Większość interfejsów API animacji w Compose obsługuje domyślnie wartości animacji Float
, Color
, Dp
i inne podstawowe typy danych, ale czasami trzeba animować inne typy danych, w tym niestandardowe. Podczas animacji każda wartość animacji jest reprezentowana jako AnimationVector
. Wartość jest konwertowana na
AnimationVector
i na odwrót za pomocą odpowiedniego TwoWayConverter
, aby system animacji mógł je obsługiwać w sposób jednolity. Na przykład Int
jest reprezentowane jako AnimationVector1D
, które zawiera pojedynczą wartość zmiennoprzecinkową.
TwoWayConverter
dla Int
wygląda tak:
val IntToVector: TwoWayConverter<Int, AnimationVector1D> = TwoWayConverter({ AnimationVector1D(it.toFloat()) }, { it.value.toInt() })
Color
to w podstawie zestaw 4 wartości: czerwony, zielony, niebieski i alfa, więc Color
jest konwertowane na AnimationVector4D
, które zawiera 4 wartości zmiennoprzecinkowe. W ten sposób każdy typ danych używany w animacjach jest konwertowany na AnimationVector1D
, AnimationVector2D
, AnimationVector3D
lub AnimationVector4D
w zależności od wymiarowości. Dzięki temu różne komponenty obiektu mogą być animowane niezależnie, z własnym śledzeniem prędkości. Domyślne konwertery dla podstawowych typów danych można wywołać za pomocą konwerterów takich jak Color.VectorConverter
lub Dp.VectorConverter
.
Jeśli chcesz dodać obsługę nowego typu danych jako wartości animacji, możesz utworzyć własną wartość TwoWayConverter
i przekazać ją do interfejsu API. Możesz na przykład użyć funkcji animateValueAsState
, aby animować niestandardowy typ danych w ten sposób:
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" ) }
Na liście znajdują się niektóre wbudowane VectorConverter
:
Color.VectorConverter
Dp.VectorConverter
Offset.VectorConverter
Int.VectorConverter
Float.VectorConverter
IntSize.VectorConverter
Polecane dla Ciebie
- Uwaga: tekst linku jest wyświetlany, gdy obsługa JavaScript jest wyłączona
- Animacje na podstawie wartości
- Etapy tworzenia kodu {:#iterative-code-dev }
- Animacje w Compose