Как связать вместе две части анимации в джетпаке, чтобы смещение увеличивалось, а затем уменьшалось?
Недавно я занялся созданием анимации с помощью компоновки реактивного ранца, и мне интересно, как вы можете сделать так, чтобы при увеличении значения смещения, как только анимация достигает этого значения, она затем изменяла значение на другое значение. Таким образом, как обновление перехода, но вместо того, чтобы в то же время, один за другим.
3 ответа
На самом деле ответ @RaBaKa частично правильный, но в нем отсутствует информация о том, как следует запускать анимацию.
Это должно быть сделано как побочный эффект. Например, вы можете использовать
LaunchedEffect
: он уже запущен в области действия сопрограммы. Совершенно нормально запускать одну анимацию за другой — как только завершится первая функция приостановки, запустится вторая:
val value = remember { Animatable(0f) }
LaunchedEffect(Unit) {
value.animateTo(
20f,
animationSpec = tween(2000),
)
value.animateTo(
10f,
animationSpec = tween(2000),
)
}
Text(value.value.toString())
Если вы хотите сделать это в ответ на какое-то действие, например нажатие кнопки, вам нужно запустить сопрограмму самостоятельно. Главное запускать анимации в одной сопрограмме, чтобы они были сцеплены.
val value = remember { Animatable(0f) }
val scope = rememberCoroutineScope()
Button(onClick = {
scope.launch {
value.animateTo(
20f,
animationSpec = tween(2000),
)
value.animateTo(
10f,
animationSpec = tween(2000),
)
}
}) {
}
Text(value.value.toString())
Правильный ответ - использовать сопрограммы kotlin, мне удалось заставить его работать нормально, вы должны использовать сопрограммы, чтобы запускать анимацию в правильной последовательности, чтобы это выглядело как
animationRoutine.launch {
coroutineScope {
launch {
animate(
startingValue,
targetValue,
animationSpec = whatYouWant,
block = { value, _ -> whateverYouNeed = value })
}
launch {
animate(
initialValue,
targetValue,
animationSpec = whatYouWant,
block = { value, _ -> whateverYouNeed = value })
}
}
Каждая из областей запуска запускает все неблокирующим образом, если вы укажете ему разрешить вам запускать несколько анимаций одновременно на более низком уровне, а для последовательности анимаций вы добавляете еще одну сопрограмму для следующей части анимации.
Может быть, вы можете использовать
Animatable
val value = remember { Animatable(0f) } //Initial Value
Затем в композиции вы можете просто использовать
value.animateTo(20f)
тогда
value.animateTo(10f)
Для получения дополнительной информации посетите официальную документацию