Многие API анимации обычно принимают параметры для настройки своего поведения.
Как настроить анимацию с помощью параметра AnimationSpec
Большинство API для анимации позволяют разработчикам настраивать ее параметры с помощью необязательного параметра 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" )
Существуют разные виды AnimationSpec, которые используются для создания разных типов анимации.
Создание анимации на основе физики с помощью spring
spring создает анимацию на основе физики между начальным и конечным значениями. Он принимает два параметра: dampingRatio и stiffness.
dampingRatio определяет, насколько упругой должна быть пружина. Значение по умолчанию – Spring.DampingRatioNoBouncy.
stiffness определяет, насколько быстро пружина должна двигаться к конечному значению. Значение по умолчанию – Spring.StiffnessMedium.
val value by animateFloatAsState( targetValue = 1f, animationSpec = spring( dampingRatio = Spring.DampingRatioHighBouncy, stiffness = Spring.StiffnessMedium ), label = "spring spec" )
spring лучше справляется с прерываниями, чем типы на основе длительности,AnimationSpec поскольку гарантирует непрерывность скорости при изменении целевого значения во время анимации. spring используется в качестве AnimationSpec по умолчанию многими API анимации, например animate*AsState и updateTransition.
Например, если применить конфигурацию spring к следующей анимации, которая запускается при касании экрана пользователем, то при прерывании анимации можно заметить, что метод tween реагирует не так плавно, как spring.
tween и spring для анимации и ее прерывание.Анимировать переход между начальным и конечным значениями с помощью кривой смягчения с параметром tween.
tween анимирует переход между начальным и конечным значениями в течение указанного времени durationMillis, используя кривую смягчения. tween – это сокращение от слова "между" (between), поскольку оно используется между двумя значениями.
Вы также можете указать delayMillis, чтобы отложить начало анимации.
val value by animateFloatAsState( targetValue = 1f, animationSpec = tween( durationMillis = 300, delayMillis = 50, easing = LinearOutSlowInEasing ), label = "tween delay" )
Подробнее о смягчении…
Анимируйте переход к определенным значениям в заданное время с помощью keyframes.
keyframes анимируется на основе значений, указанных в разные моменты времени в течение анимации. В любой момент времени значение анимации будет интерполироваться между двумя значениями ключевых кадров. Для каждого из этих ключевых кадров можно указать сглаживание, чтобы определить кривую интерполяции.
Указывать значения в начале и конце видео необязательно. Если вы не укажете эти значения, по умолчанию будут использоваться начальное и конечное значения анимации.
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" )
Плавная анимация между ключевыми кадрами с помощью keyframesWithSplines
Чтобы создать анимацию, которая плавно переходит между значениями, можно использовать keyframesWithSplines вместо спецификаций анимации keyframes.
val offset by animateOffsetAsState( targetValue = Offset(300f, 300f), animationSpec = keyframesWithSpline { durationMillis = 6000 Offset(0f, 0f) at 0 Offset(150f, 200f) atFraction 0.5f Offset(0f, 100f) atFraction 0.7f } )
Ключевые кадры на основе сплайнов особенно полезны для двумерного движения объектов на экране.
В приведенных ниже видео показаны различия между полями keyframes и keyframesWithSpline при одинаковых координатах x и y, по которым должен двигаться круг.
keyframes
|
keyframesWithSplines
|
|---|---|
Как видите, ключевые кадры на основе сплайнов обеспечивают более плавные переходы между точками, поскольку для анимации между объектами используются кривые Безье. Этот параметр полезен для предустановленной анимации. Однако при работе с точками, управляемыми пользователем, лучше использовать пружины, чтобы обеспечить плавность перехода между точками, поскольку их можно прервать.
Как повторить анимацию с помощью repeatable
repeatable запускает анимацию на основе продолжительности (например, tween или keyframes) несколько раз, пока не будет достигнуто указанное количество итераций. Вы можете передать параметр repeatMode, чтобы указать, должна ли анимация повторяться, начиная с начала (RepeatMode.Restart) или с конца (RepeatMode.Reverse).
val value by animateFloatAsState( targetValue = 1f, animationSpec = repeatable( iterations = 3, animation = tween(durationMillis = 300), repeatMode = RepeatMode.Reverse ), label = "repeatable spec" )
Как зациклить анимацию с помощью infiniteRepeatable
infiniteRepeatable похож на repeatable, но повторяется бесконечное количество раз.
val value by animateFloatAsState( targetValue = 1f, animationSpec = infiniteRepeatable( animation = tween(durationMillis = 300), repeatMode = RepeatMode.Reverse ), label = "infinite repeatable" )
В тестах, использующих ComposeTestRule, анимация с infiniteRepeatable не выполняется. Компонент будет отрисован с использованием начального значения каждого анимированного значения.
Сразу привязать к конечному значению с помощью snap
snap – это специальный AnimationSpec, который сразу переключает значение на конечное. Вы можете указать значение delayMillis, чтобы отложить начало анимации.
val value by animateFloatAsState( targetValue = 1f, animationSpec = snap(delayMillis = 50), label = "snap spec" )
Как задать собственную функцию сглаживания
Операции AnimationSpec, основанные на продолжительности (например, tween или keyframes), используют Easing для корректировки доли анимации. Это позволяет анимированному значению ускоряться и замедляться, а не двигаться с постоянной скоростью. Доля – это значение от 0 (начало) до 1,0 (конец), указывающее текущую точку анимации.
Сглаживание – это функция, которая принимает дробное значение от 0 до 1,0 и возвращает число с плавающей запятой. Возвращаемое значение может выходить за границы, чтобы показать перелет или недолет. Собственный вариант Easing можно создать с помощью кода, приведенного ниже.
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 есть несколько встроенных функций Easing, которые охватывают большинство вариантов использования.
Подробнее о том, какую динамику использовать в разных ситуациях, можно узнать в руководстве по внедрению Material Design.
FastOutSlowInEasingLinearOutSlowInEasingFastOutLinearEasingLinearEasingCubicBezierEasing- Посмотрите
Анимировать пользовательские типы данных, преобразуя их в AnimationVector и обратно.
Большинство API анимации Compose по умолчанию поддерживают Float, Color, Dp и другие базовые типы данных в качестве значений анимации, но иногда вам нужно анимировать другие типы данных, в том числе пользовательские. Во время анимации любое анимированное значение обозначается как AnimationVector. Значение преобразуется в AnimationVector и наоборот с помощью соответствующего TwoWayConverter, чтобы основная система анимации могла обрабатывать их единообразно. Например, Int представлен как AnimationVector1D, содержащий одно значение с плавающей запятой.
TwoWayConverter для Int выглядит следующим образом:
val IntToVector: TwoWayConverter<Int, AnimationVector1D> = TwoWayConverter({ AnimationVector1D(it.toFloat()) }, { it.value.toInt() })
Color – это набор из четырех значений: красного, зеленого, синего и альфа-канала. Поэтому Color преобразуется в AnimationVector4D, содержащий четыре значения с плавающей запятой. Таким образом, все типы данных, используемые в анимации, преобразуются в AnimationVector1D, AnimationVector2D, AnimationVector3D или AnimationVector4D в зависимости от их размерности. Это позволяет анимировать разные компоненты объекта независимо друг от друга, каждый со своей скоростью. Встроенные конвертеры для основных типов данных можно вызвать с помощью таких конвертеров, как Color.VectorConverter или Dp.VectorConverter.
Если вы хотите добавить поддержку нового типа данных в качестве анимированного значения, создайте собственный атрибут TwoWayConverter и передайте его в API. Например, вы можете использовать animateValueAsState, чтобы анимировать специальный тип данных следующим образом:
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" ) }
Ниже приведены некоторые встроенные VectorConverter:
Color.VectorConverterDp.VectorConverterOffset.VectorConverterInt.VectorConverterFloat.VectorConverterIntSize.VectorConverter
Рекомендуем
- Примечание. Текст ссылки показывается, когда JavaScript отключен.
- Анимации на основе ценности
- Итеративная разработка кода {:#iterative-code-dev }
- Анимация в Compose