Многие 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" )
Повторите анимацию с помощью 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