前言前面课程学习了布局、状态、列表分页、Canvas手绘。Compose不再依靠xml写动画全部是声明式动画。状态发生变化框架自动插值产生动画。本节课学习基础动画API animate*AsState 、 AnimatedVisibility 、 Transition 掌握组件显隐、尺寸、颜色渐变。知识点清单Compose声明式动画核心思想状态驱动动画状态一变动画自动跑animate*AsState单一值动画颜色、尺寸、偏移AnimatedVisibility组件显示隐藏入场、退场Transition多属性同时动画一个状态变更同时驱动多个动画简单Demo按钮控制方块缩放变色、显示消失完整示例源码importandroidx.compose.animation.AnimatedVisibilityimportandroidx.compose.animation.animateColorAsStateimportandroidx.compose.animation.animateSizeAsStateimportandroidx.compose.animation.core.animateDpAsStateimportandroidx.compose.animation.fadeInimportandroidx.compose.animation.fadeOutimportandroidx.compose.animation.scaleInimportandroidx.compose.animation.scaleOutimportandroidx.compose.animation.transitionimportandroidx.compose.foundation.backgroundimportandroidx.compose.foundation.layout.Arrangementimportandroidx.compose.foundation.layout.Boximportandroidx.compose.foundation.layout.Columnimportandroidx.compose.foundation.layout.sizeimportandroidx.compose.material3.Buttonimportandroidx.compose.material3.Textimportandroidx.compose.runtime.Composableimportandroidx.compose.runtime.getValueimportandroidx.compose.runtime.mutableStateOfimportandroidx.compose.runtime.rememberimportandroidx.compose.runtime.setValueimportandroidx.compose.ui.Alignmentimportandroidx.compose.ui.Modifierimportandroidx.compose.ui.Colorimportandroidx.compose.ui.unit.dpenumclassBoxState{Small,Large}ComposablefunAnimationBasicScreen(){//布尔开关控制方块状态vartogglebyremember{mutableStateOf(false)}//枚举状态用于Transition演示varboxStatebyremember{mutableStateOf(BoxState.Small)}//单一值动画dp尺寸动画valtargetSizebyanimateDpAsState(targetValueif(toggle)200.dpelse80.dp,labelsizeAnim)//单一值动画颜色动画valtargetColorbyanimateColorAsState(targetValueif(toggle)Color(0xFF2196F3)elseColor(0xFFFF5722),labelcolorAnim)Column(modifierModifier,horizontalAlignmentAlignment.CenterHorizontally,verticalArrangementArrangement.spacedBy(20.dp)){Button(onClick{toggle!toggle}){Text(切换方块(animate*AsState))}Box(modifierModifier.size(targetSize).background(targetColor))//AnimatedVisibility 显隐动画Button(onClick{boxStateif(boxStateBoxState.Small)BoxState.LargeelseBoxState.Small}){Text(控制方块显示隐藏‑AnimatedVisibility)}AnimatedVisibility(visibleboxStateBoxState.Large,enterfadeIn()scaleIn(),exitfadeOut()scaleOut()){Box(modifierModifier.size(120.dp).background(Color(0xFF4CAF50)))}}}逐行解读Compose动画核心思想状态驱动传统Android View体系先定义动画资源xml之后调用 start() 手动启动动画。Compose声明式动画只修改业务状态框架自动对比旧值和目标值中间插值自动播放动画。不需要手动调用start。animate*AsState系列animateDpAsState / animateColorAsState适合单个属性做动画返回一个经过动画插值之后的值直接给到size、background。targetValue动画的目标值当这个值发生改变自动开始插值动画。label参数用于动画调试预览Android Studio动画预览工具识别。局限一次只能驱动一个属性如果希望同时驱动尺寸、颜色、偏移多个属性适合使用Transition。AnimatedVisibility组件入场退场专门控制组件显示与消失visible布尔状态true显示false消失enter入场动画可以使用叠加多种动画效果fadeIn淡入 scaleIn放大进入exit退场动画fadeOut淡出 scaleOut缩小消失。注意不是简单的gone/invisible组件在退场期间仍然存在执行完退场动画之后才从组件树移除。Transition多属性同时动画Transition基于状态布尔或者枚举一个状态切换同时驱动多个动画颜色大小偏移。AnimatedVisibility内部底层其实就是基于Transition封装出来的高层API。业务场景页面卡片从状态A完整过渡到状态B同时尺寸、圆角、颜色一起变化优先Transition。动画的速度控制animationSpec所有的animate*AsState都可以传入animationSpec可以设置持续时长、阻尼弹性动画spring弹簧动画、tween补间。tween指定时间的线性/缓动补间spring弹簧物理动画有回弹效果Compose里面非常推荐使用弹簧动画。容易踩坑❌ 试图手动调用start()启动动画Compose动画依靠修改状态来驱动没有start函数。❌ AnimatedVisibility直接修改visibility属性不要手动控制组件是否渲染交给AnimatedVisibility管理组件树。❌ 动画状态放在ViewModel里面的时候注意动画过程当中频繁的值不适合存ViewModelViewModel适合保存目标业务状态动画插值中间值交给Compose运行时内部维护。❌ 动画执行过程当中反复快速切换状态Compose支持动画打断与换向会平滑切换到新目标不需要开发者处理中断逻辑。✅ animate*AsState适合单个属性AnimatedVisibility专门做显隐Transition适合多属性联动修改业务状态触发动画spring弹簧动画优先选用。多元化习题练习习题1【基础‑改错题】开发按照旧View思路想找Compose动画的start()启动方法找不到为什么答案Compose动画是声明式状态驱动不需要调用start修改targetValue对应的业务状态框架自动插值播放动画。解读思维需要从命令式启动动画转向状态驱动。习题2【基础‑代码修改题】给animateDpAsState增加动画规格使用tween动画持续600毫秒。答案valtargetSizebyanimateDpAsState(targetValueif(toggle)200.dpelse80.dp,animationSpecandroidx.compose.animation.core.tween(durationMillis600),labelsizeAnim)解读animationSpec参数控制动画时间、插值曲线。习题3【进阶‑补充代码题】AnimatedVisibility入场希望同时实现淡入 从上往下滑入如何写enter答案enterfadeIn()androidx.compose.animation.slideInVertically()解读使用加号运算符叠加多种入场动画效果。习题4【综合‑逻辑应用题】animateAsState 和 Transition二者适用场景怎么区分答案animateAsState适合只对单独一个属性执行动画简单轻量Transition同一个状态变更同时驱动多个属性大小颜色偏移圆角一起变化适合卡片完整状态切换。AnimatedVisibility是Transition上层封装。解读优先高层API复杂多属性联动再使用Transition。习题5【概念简答题】spring弹簧动画对比tween时间补间动画效果上有什么区别答案tween严格按照设定的毫秒时间完成动画匀速或者指定缓动曲线spring是物理仿真弹簧没有固定时长会有轻微回弹震荡交互反馈更加生动适合点击反馈。解读Material3组件大量内部使用spring弹簧动画。本节课知识点总结Compose动画核心理念状态驱动动画修改业务状态自动插值播放动画没有start()方法分为tween固定时长补间、spring弹簧物理动画。animate*AsState系列API适合单一属性动画dp、color、offset。AnimatedVisibility高层API专门用于组件的显示和消失支持入场enter退场exit可以使用叠加多种动画效果。Transition底层API用于一个状态变更同时驱动多项属性联动动画AnimatedVisibility基于Transition实现。业务目标状态可以上ViewModel动画运行过程的中间插值值由Compose框架维护不要保存到ViewModel。下一课预告第18课 权限、WorkManager后台任务Compose当中处理系统服务
