Как использовать анимации в Jetpack Compose?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Использование анимаций в Jetpack Compose
В Jetpack Compose анимации реализованы декларативно и тесно интегрированы с системой рекомпозиции. В отличие от View-системы, где анимации были императивными и управлялись объектами, Compose предлагает мощный набор API для создания плавных и отзывчивых анимаций.
Основные API анимаций
1. AnimatedVisibility - анимация появления/исчезновения
Самый простой способ анимировать появление и исчезновение элемента:
var visible by remember { mutableStateOf(true) }
AnimatedVisibility(
visible = visible,
enter = fadeIn() + expandHorizontally(),
exit = fadeOut() + shrinkHorizontally()
) {
Text("Анимированный текст")
}
2. animate*AsState функции
Эти функции автоматически анимируют изменения значений состояния:
var enabled by remember { mutableStateOf(true) }
val backgroundColor by animateColorAsState(
targetValue = if (enabled) Color.Green else Color.Red,
animationSpec = tween(durationMillis = 300)
)
Box(
modifier = Modifier
.size(100.dp)
.background(backgroundColor)
.clickable { enabled = !enabled }
)
3. updateTransition для сложных анимаций
Позволяет анимировать несколько значений одновременно:
enum class ButtonState { Pressed, Released }
val currentState = remember { mutableStateOf(ButtonState.Released) }
val transition = updateTransition(currentState.value, label = "button")
val size by transition.animateDp(
transitionSpec = { spring(dampingRatio = 0.5f) },
label = "size"
) { state ->
when (state) {
ButtonState.Pressed -> 80.dp
ButtonState.Released -> 100.dp
}
}
val color by transition.animateColor(
label = "color"
) { state ->
when (state) {
ButtonState.Pressed -> Color.Red
ButtonState.Released -> Color.Blue
}
}
Спецификации анимаций (AnimationSpec)
Compose предоставляет различные AnimationSpec для настройки поведения анимаций:
- tween - анимация с заданной длительностью и кривой easing
- spring - физически точная анимация с пружинным эффектом
- keyframes - анимация по ключевым кадрам
- repeatable - повторяющаяся анимация
- infiniteRepeatable - бесконечно повторяющаяся анимация
val animatedValue by animateFloatAsState(
targetValue = target,
animationSpec = spring(
dampingRatio = Spring.DampingRatioMediumBouncy,
stiffness = Spring.StiffnessLow
)
)
Практические примеры
Анимация перехода между экранами:
@Composable
fun AnimatedScreenTransition(content: @Composable () -> Unit) {
val transition = rememberInfiniteTransition()
val offset by transition.animateFloat(
initialValue = 0f,
targetValue = 360f,
animationSpec = infiniteRepeatable(
animation = tween(2000, easing = LinearEasing),
repeatMode = RepeatMode.Reverse
)
)
Box(
modifier = Modifier
.graphicsLayer {
rotationZ = offset
}
) {
content()
}
}
Анимация загрузки:
@Composable
fun LoadingAnimation() {
val infiniteTransition = rememberInfiniteTransition()
val alpha by infiniteTransition.animateFloat(
initialValue = 0.3f,
targetValue = 1f,
animationSpec = infiniteRepeatable(
animation = keyframes {
durationMillis = 1000
0.3f at 0
1f at 500
0.3f at 1000
},
repeatMode = RepeatMode.Restart
)
)
CircularProgressIndicator(
modifier = Modifier
.alpha(alpha)
.size(50.dp)
)
}
Лучшие практики
- Используйте
rememberдля хранения состояния анимации, чтобы избежать перезапуска при рекомпозиции - Оптимизируйте производительность - избегайте анимаций на каждом кадре рекомпозиции
- Учитывайте пользовательский опыт - анимации должны быть быстрыми (200-300 мс) и осмысленными
- Тестируйте на разных устройствах - производительность анимаций может отличаться
- Используйте
LaunchedEffectдля запуска анимаций в ответ на события:
LaunchedEffect(key1 = someState) {
// Запуск анимации при изменении состояния
animateTo(targetValue, animationSpec = tween(300))
}
Отладка анимаций
Для отладки используйте модификатор graphicsLayer и отслеживайте значения через println или Android Studio Debugger. Compose также предоставляет инструменты для проверки частоты кадров анимаций в реальном времени.
Jetpack Compose делает создание анимаций интуитивно понятным и типобезопасным, позволяя разработчикам сосредоточиться на творческой части, а не на технической реализации.