Dostosuj animacje

Wiele interfejsów API animacji często akceptuje parametry zachowanie użytkownika.

Dostosuj animacje za pomocą parametru AnimationSpec

Większość interfejsów API animacji umożliwia programistom dostosowywanie specyfikacji animacji przez opcjonalny parametr 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)
)

Istnieją różne rodzaje elementów AnimationSpec do tworzenia różnych typów animację.

Twórz oparte na fizyce animacje w spring

spring tworzy opartą na fizyce animację między wartością początkową a końcową. it przyjmuje 2 parametry: dampingRatio i stiffness.

dampingRatio określa dynamikę wiosny. Wartość domyślna to Spring.DampingRatioNoBouncy

Rysunek 1. Ustawienie różnych współczynników tłumienia sprężyn.

stiffness określa, jak szybko sprężyna ma się przesuwać w kierunku wartości końcowej. wartość domyślna to Spring.StiffnessMedium.

Rysunek 2. Ustawianie różnych sztywności sprężyny

val value by animateFloatAsState(
    targetValue = 1f,
    animationSpec = spring(
        dampingRatio = Spring.DampingRatioHighBouncy,
        stiffness = Spring.StiffnessMedium
    )
)

spring radzi sobie z zakłóceniami lepiej niż na podstawie czasu trwania AnimationSpec, ponieważ gwarantuje ciągłość prędkości, gdy wartość docelowa zmienia się w obrębie animacji. Używana jest opcja spring AnimationSpec według wielu interfejsów API animacji, takich jak animate*AsState czy updateTransition

Jeśli na przykład zastosujesz konfigurację spring do tej animacji zależnej od dotknięcia użytkownika, to podczas przerywania jej odtwarzania w trakcie jej odtwarzania zauważysz, że użycie tween nie reaguje tak płynnie jak spring.

Rysunek 3. Ustawienie specyfikacji tween i spring dla animacji i jej przerwanie.

Animuj między wartością początkową a końcową za pomocą krzywej wygładzania: tween

Funkcja tween jest animowana między wartością początkową a końcową w zakresie określonym durationMillis za pomocą krzywej wygładzania. tween to skrót od słowa między - i oznacza między dwiema wartościami.

Możesz też określić delayMillis, aby opóźnić początek animacji.

val value by animateFloatAsState(
    targetValue = 1f,
    animationSpec = tween(
        durationMillis = 300,
        delayMillis = 50,
        easing = LinearOutSlowInEasing
    )
)

Więcej informacji znajdziesz w sekcji Wygładzanie.

Używaj funkcji keyframes, aby w określonych momentach wyświetlać animacje pod kątem określonych wartości

keyframes jest animowany na podstawie wartości zrzutu określonych w różnych sygnatury czasowe w czasie trwania animacji. W każdym momencie animacja będzie interpolowana między 2 wartościami klatek kluczowych. W przypadku każdej z tych opcji klatek kluczowych, można określić wygładzanie, aby określić krzywą interpolacji.

Określenie wartości z zakresu 0 ms i czasu trwania jest opcjonalne. Jeśli tak, nie określają tych wartości, domyślnie ustawiają one wartość początkową i końcową parametru ani animacji.

val value by animateFloatAsState(
    targetValue = 1f,
    animationSpec = keyframes {
        durationMillis = 375
        0.0f at 0 with LinearOutSlowInEasing // for 0-15 ms
        0.2f at 15 with FastOutLinearInEasing // for 15-75 ms
        0.4f at 75 // ms
        0.4f at 225 // ms
    }
)

Powtarzanie animacji przy użyciu funkcji repeatable

repeatable uruchamia animację opartą na czasie trwania (np. tween lub keyframes) aż do osiągnięcia określonej liczby iteracji. Możesz przekazać Parametr repeatMode określający, czy animacja ma się powtarzać od początku (RepeatMode.Restart) lub od końca (RepeatMode.Reverse).

val value by animateFloatAsState(
    targetValue = 1f,
    animationSpec = repeatable(
        iterations = 3,
        animation = tween(durationMillis = 300),
        repeatMode = RepeatMode.Reverse
    )
)

Powtarzaj animację w nieskończoność przy użyciu funkcji infiniteRepeatable

infiniteRepeatable jest jak repeatable, ale powtarza się w nieskończoność powtórzeń.

val value by animateFloatAsState(
    targetValue = 1f,
    animationSpec = infiniteRepeatable(
        animation = tween(durationMillis = 300),
        repeatMode = RepeatMode.Reverse
    )
)

W testach przy użyciu ComposeTestRule animacje korzystające z metody infiniteRepeatable nie są uruchamiane. Komponent zostanie renderowanych na podstawie początkowej wartości każdej wartości animowanej.

Natychmiast przyciągaj do wartości końcowej za pomocą funkcji snap

snap to specjalny element AnimationSpec, który natychmiast przełącza wartość na wartość końcową. Możesz określić delayMillis, aby opóźnić rozpoczęcie transmisji animację.

val value by animateFloatAsState(
    targetValue = 1f,
    animationSpec = snap(delayMillis = 50)
)

Ustawianie niestandardowej funkcji wygładzania

Użycie operacji AnimationSpec (np. tween lub keyframes) na podstawie czasu trwania Easing, aby dostosować ułamek animacji. Dzięki temu wartość animacji przyspieszać i zwalniać, a nie poruszać się w stałym tempie. Ułamek to wartość z zakresu od 0 (początek) do 1,0 (koniec) wskazująca bieżący punkt w animację.

Wygładzanie jest w rzeczywistości funkcją, która przyjmuje wartość ułamkową od 0 do 1,0 i zwraca liczbę zmiennoprzecinkową. Zwrócona wartość może znajdować się poza granicą i odzwierciedlać zbyt długi lub zbyt krótki. Możesz utworzyć niestandardowe wygładzanie jak w poniższym kodzie.

val CustomEasing = Easing { fraction -> fraction * fraction }

@Composable
fun EasingUsage() {
    val value by animateFloatAsState(
        targetValue = 1f,
        animationSpec = tween(
            durationMillis = 300,
            easing = CustomEasing
        )
    )
    // ……
}

Tworzenie wiadomości udostępnia kilka wbudowanych funkcji Easing, które mają zastosowanie w większości przypadków. Więcej informacji znajdziesz w sekcji Szybkość – styl Material Design. informacje na temat wygładzania, z którego należy skorzystać w zależności od sytuacji.

  • FastOutSlowInEasing
  • LinearOutSlowInEasing
  • FastOutLinearEasing
  • LinearEasing
  • CubicBezierEasing
  • Pokaż więcej
.

Animuj niestandardowe typy danych, konwertując je z i do AnimationVector

Większość interfejsów API animacji tworzenia wiadomości obsługuje Float, Color, Dp i inne podstawowe dane jako wartości animacji, ale czasami trzeba innych typów danych, w tym danych niestandardowych. Podczas animacji wszystkie animacje wartość jest reprezentowana jako AnimationVector. Wartość jest konwertowana na AnimationVector i na odwrót o odpowiednią wartość w polu TwoWayConverter, tak aby podstawowy system animacji radzi sobie z nimi równomiernie. Na przykład Int to reprezentowany jako AnimationVector1D z pojedynczą wartością zmiennoprzecinkową. TwoWayConverter dla Int wygląda tak:

val IntToVector: TwoWayConverter<Int, AnimationVector1D> =
    TwoWayConverter({ AnimationVector1D(it.toFloat()) }, { it.value.toInt() })

Color to zasadniczo zestaw 4 wartości: czerwonego, zielonego, niebieskiego i alfa, więc Pole Color jest przekształcane na typ AnimationVector4D, który zawiera 4 wartości zmiennoprzecinkowe. W 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 jego wymiarów. Dzięki temu różne niezależnie od siebie animowanych komponentów obiektu, śledzenie prędkości. Możliwość uzyskiwania dostępu do wbudowanych konwerterów dla podstawowych typów danych korzysta z konwersji, takich jak Color.VectorConverter lub Dp.VectorConverter.

Jeśli chcesz dodać obsługę nowego typu danych jako wartości animacji, możesz utworzyć własny TwoWayConverter i przekazać go do interfejsu API. Na przykład: może użyć elementu animateValueAsState, aby animować Twój 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)
            }
        )
    )
}

Ta lista zawiera niektóre wbudowane komponenty VectorConverter:

. .