Многие 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
создает основанную на физике анимацию между начальными и конечными значениями. Он принимает 2 параметра: dampingRatio
и stiffness
.
dampingRatio
определяет, насколько упругой должна быть пружина. Значение по умолчанию — Spring.DampingRatioNoBouncy
.
Рисунок 1. Настройка различных коэффициентов демпфирования пружины.
stiffness
определяет, насколько быстро пружина должна двигаться к конечному значению. Значение по умолчанию — Spring.StiffnessMedium
.
Рисунок 2. Настройка различной жесткости пружины
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
.
Рисунок 3. Установка спецификаций tween
vs spring
для анимации и ее прерывание.
Анимация между начальным и конечным значениями с помощью кривой замедления с помощью tween
tween
анимирует между начальным и конечным значениями в течение заданной durationMillis
используя кривую замедления. tween
— это сокращение от слова «между» — поскольку оно происходит между двумя значениями.
Вы также можете указать delayMillis
чтобы отложить начало анимации.
val value by animateFloatAsState( targetValue = 1f, animationSpec = tween( durationMillis = 300, delayMillis = 50, easing = LinearOutSlowInEasing ), label = "tween delay" )
См. раздел «Ускорение» для получения дополнительной информации.
Анимация до определенных значений в определенные моменты времени с помощью keyframes
keyframes
анимируются на основе значений моментального снимка, указанных в разные временные метки во время анимации. В любой момент времени значение анимации будет интерполировано между двумя значениями ключевого кадра. Для каждого из этих ключевых кадров можно указать замедление для определения кривой интерполяции.
Необязательно указывать значения для 0 мс и времени продолжительности. Если вы не укажете эти значения, по умолчанию они будут равны начальному и конечному значениям анимации соответственно.
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 и возвращает число с плавающей запятой. Возвращаемое значение может находиться за пределами границы, обозначая превышение или недостижение. Пользовательское замедление можно создать, как показано в приведенном ниже коде.
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» для получения дополнительной информации о том, какое Easing можно использовать в зависимости от вашего сценария.
-
FastOutSlowInEasing
-
LinearOutSlowInEasing
-
FastOutLinearEasing
-
LinearEasing
-
CubicBezierEasing
- Посмотреть больше
Анимация пользовательских типов данных путем преобразования в 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
представляет собой набор из 4 значений: красного, зеленого, синего и альфа, поэтому Color
преобразуется в AnimationVector4D
, который содержит 4 значения с плавающей запятой. Таким образом, каждый тип данных, используемый в анимации, преобразуется в 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.VectorConverter
-
Dp.VectorConverter
-
Offset.VectorConverter
-
Int.VectorConverter
-
Float.VectorConverter
-
IntSize.VectorConverter
Рекомендуется для вас
- Примечание: текст ссылки отображается, когда JavaScript отключен.
- Анимация на основе значений
- Итеративная разработка кода {:#iterative-code-dev }
- Анимации в Compose