Jetpack Compose 提供了一系列功能强大且可扩展的 API,可用于在应用界面中轻松实现各种动画效果。这一系列文章会逐个介绍所有的动画 API,通过最直观的 Demo 示例,手把手教你怎么写动画以及带你了解动画背后的原理。
📑 手把手教你写 Compose 动画 - - 状态转移型动画 API:animate*AsState()
📑 手把手教你写 Compose 动画 - - 流程定制型动画 API:Animatable()
📑 手把手教你写 Compose 动画 - - 讲的不能再细的 AnimationSpec 动画规范
📑 手把手教你写 Compose 动画 - - 过渡动画 API:Transition
📑 手把手教你写 Compose 动画 - - 显示与消失 API:AnimatedVisibility
📑 手把手教你写 Compose 动画 - - 简单页面切换动画 API:Crossfade
📑 手把手教你写 Compose 动画 - - 更强大的多组件切换动画 API:AnimatedContent
📑 手把手教你写 Compose 动画 - - 组件大小变化 API:animateContentSize
📓 动画图表
在每一篇文章开头,我都会放一张 Compose 动画 API 的图表,以便你有最直观的感受。
📓 animateContentSize()
animateContentSize 修饰符可为 Compose 组件大小变化时添加动画效果。
还是那句话:探索新技术的最佳方式是尝试它们,我们先构建一个简单场景:
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
animateContentSizeTest()
}
}
}
@Composable
fun animateContentSizeTest() {
var longString by remember { mutableStateOf(false) }
val text by remember(longString) {
mutableStateOf(
if (longString) "Hi, Compose, this is long description!"
else "Hi, Compose!"
)
}
Column (
modifier = Modifier.fillMaxWidth(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Spacer(modifier = Modifier.height(100.dp))
Button(
onClick = {
longString = !longString
}
) {
Text(text = "改变 Text 长度")
}
Box(
Modifier
.background(Color.Green)) {
Text(text = text)
}
}
}
现在你看这段代码应该毫无压力了,我们看下效果:
可以看出来,Box 的长度会随着 Text 组件的文字长度而变化,但是这种长度变化很明显没有动画效果。
如果我们想让 Box 组件长度变化也有动画效果的话,就可以使用 animateContentSize 修饰符。
既然是修饰符,那肯定就是用在 Modifier 中的,所以代码写起来也很简单:
Box(
Modifier
.background(Color.Green)
.animateContentSize()) { // 只需要对 Box 添加 Modifier.animateContentSize()
Text(text = text)
}
就这么简单,我们看下效果:
animateContentSize() 的用法就这么简单,我们再来看下它的定义:
fun Modifier.animateContentSize(
animationSpec: FiniteAnimationSpec<IntSize> = spring(),
finishedListener: ((initialValue: IntSize, targetValue: IntSize) -> Unit)? = null
)
它同样可以自行设定动画曲线(默认是弹簧效果 - - 不弹),现在我们试下它能够弹的效果:
Box(
Modifier
.background(Color.Green)
.animateContentSize(animationSpec = spring(Spring.DampingRatioHighBouncy))) {
Text(text = text)
}