第 2 节 — 在 Jetpack Compose 中编排复杂的动画
在本节中,我们将深入研究在 Jetpack Compose 中编排复杂动画的方式。我们专注于创建多个元素无缝交互的同步动画,从而增强整体用户体验。
A) 连锁反应动画——多米诺骨牌效应
在 UI 中创建多米诺骨牌效果可以通过设置一系列动画来实现,其中一个动画的完成会触发下一个动画的开始。
@Composable
fun DominoEffect() {
val animatedValues = List(6) { remember { Animatable(0f) } }
LaunchedEffect(Unit) {
animatedValues.forEachIndexed { index, animate ->
animate.animateTo(
targetValue = 1f,
animationSpec = tween(durationMillis = 1000, delayMillis = index * 100)
)
}
}
Box (modifier = Modifier.fillMaxSize()){
animatedValues.forEachIndexed { index, value ->
Box(
modifier = Modifier
.size(50.dp)
.offset(x = ((index+1) * 50).dp, y = ((index+1) * 30).dp)
.background(getRandomColor(index).copy(alpha = value.value))
)
}
}
}
fun getRandomColor(seed: Int): Color {
val random = Random(seed = seed).nextInt(256)
return Color(random, random, random)
}
- animatedValues是一个Animatable值列表,控制每个值框的不透明度。
- LaunchedEffect 为创建这些一系列交错效果而创建的动画,其中每个框在前一个框之后淡入,类似于多米诺骨牌倒下。
- getRandomColor为每个框生成随机的灰色阴影,为序列中的每个组件添加独特的视觉元素。
- 这些盒子位于屏幕的对角线上,增强了多米诺骨牌效
B) 交互式可滚动时间轴
在此时间轴中,当用户滚动时间轴时,每个元素都会淡入并移动到位。我们将Animatable用于LazyColumn列表。
@Composable
fun InteractiveTimeline(timelineItems: List<String>) {
val scrollState = rememberLazyListState()
LazyColumn(state = scrollState) {
itemsIndexed(timelineItems) { index, item ->
val animatableAlpha = remember { Animatable(0f) }
val isVisible = remember {
derivedStateOf {
scrollState.firstVisibleItemIndex <= index
}
}
LaunchedEffect(isVisible.value) {
if (isVisible.value) {
animatableAlpha.animateTo(
1f, animationSpec = tween(durationMillis = 1000)
)
}
}
TimelineItem(
text = item,
alpha = animatableAlpha.value,
)
}
}
}
@Composable
fun TimelineItem(text: String, alpha: Float) {
Row(
modifier = Modifier
.fillMaxWidth()
.background(Color.DarkGray.copy(alpha = alpha))
.padding(16.dp),
verticalAlignment = Alignment.CenterVertically
) {
Text(
text = text,
color = Color.White,
modifier = Modifier.fillMaxWidth(),
textAlign = TextAlign.Center,
fontSize = 18.sp,
fontWeight = FontWeight.SemiBold
)
}
}
- animatableAlpha控制每个时间线项目的 不透明度,最初设置为 0(完全透明)。
- 状态isVisible源自当前滚动位置,确定项目是否可见。
- 当用户滚动时,LaunchedEffect触发进入Viewport的淡入动画。
本文暂时没有评论,来添加一个吧(●'◡'●)