1. 动画基础概念:Android动画体系概述、View动画与Compose动画的对比、动画的本质与帧率

各位同学好,我是你们的老朋友。今天咱们开始聊动画——Android动画的演进之路。说实话,动画这块我踩过不少坑,也见证了整个体系从View到Compose的变迁。这一章我们先打好基础,把动画的核心概念理清楚。

1.1 动画的本质:说白了就是“视觉欺骗”

动画的本质是什么?我个人的理解很简单:在一段时间内,让视觉元素的状态连续变化。你想想看,电影24帧/秒,我们觉得流畅;游戏60帧/秒,我们觉得丝滑。其实每一帧都是静态的,只是变化够快,人眼就产生了“动”的错觉。

在Android里,动画就是控制View或Composable的属性(位置、大小、透明度、颜色等)随时间变化。这个变化不是跳变的,而是连续的——至少看起来是连续的。

核心公式:

动画 = 属性值 × 时间函数 × 帧率

属性值决定“变什么”,时间函数决定“怎么变”,帧率决定“多流畅”。

1.2 帧率:60fps是底线,120fps是追求

帧率(FPS,Frames Per Second)就是每秒刷新的画面数。Android系统默认是60fps,也就是每16.6ms刷新一帧。如果一帧的绘制时间超过16.6ms,就会掉帧——画面卡顿。

我记得有一次做列表动画,明明动画逻辑没问题,但就是卡。后来发现是布局层级太深,measure/layout耗时太长。嗯,这里要注意:动画卡顿不一定是动画代码的问题,很可能是UI渲染的瓶颈

帧率 每帧耗时 体验
30fps 33.3ms 明显卡顿,不可接受
60fps 16.6ms 流畅,Android标准
90fps 11.1ms 很流畅,高端机标配
120fps 8.3ms 丝滑,但功耗高

避坑指南:我曾经在低端机上跑60fps的动画,结果掉帧到30fps。后来发现是动画中做了大量对象创建。解决方案:用对象池复用,或者用属性动画的ValueAnimator配合setFrameDelay()控制帧率。

1.3 Android动画体系:三驾马车

Android的动画体系,说白了就是三套东西:

  • View动画(补间动画):老牌选手,Android 1.0就有了。只能对View做平移、缩放、旋转、透明度。不能改变View的真实位置——你看着它动了,但点击事件还在原地。我当年刚入行时就被这个坑过。
  • 属性动画(Property Animation):Android 3.0引入,解决了View动画的痛点。可以改变任意对象的任意属性,而且是真的改变了。比如移动一个Button,它的点击区域也跟着走。
  • Compose动画:Jetpack Compose时代的产物,声明式动画。你不需要告诉系统“怎么动”,只需要告诉系统“最终状态是什么”,系统自动帮你插值。

这三者不是替代关系,而是演进关系。View动画虽然老,但简单场景下依然好用;属性动画是View系统的中坚力量;Compose动画则是未来趋势。

1.4 View动画 vs Compose动画:一场对比

我经常被问到:“老师,现在学View动画还有用吗?”我的回答是:有用,但优先级要往后放。如果你维护的是老项目,View动画逃不掉;如果你新项目用Compose,那直接学Compose动画就行。

咱们直接看对比:

维度 View动画 Compose动画
编程范式 命令式(告诉系统每一步怎么动) 声明式(告诉系统最终状态)
可动画属性 仅限View的4种属性(平移/缩放/旋转/透明度) 任意Composable的任意属性
真实位置 不改变(点击区域还在原地) 改变(Composable真的移动了)
性能 依赖View层级,层级深则卡 基于Compose的智能重组,性能更优
代码量 较多(需要写监听器、插值器等) 较少(几行代码搞定)
学习曲线 平缓(概念简单) 陡峭(需要理解Compose状态管理)

注意:View动画的fillAfter属性是个坑。你设置了fillAfter="true",动画结束后View看起来在终点,但点击事件还在起点。我曾经因为这个被测试妹子追着问:“为什么我点不到那个按钮?”

1.5 动画的核心三要素:时长、插值器、重复行为

不管哪种动画,都离不开这三个东西:

  • 时长(Duration):动画持续多久。太短看不清,太长显得拖沓。我个人习惯:入场动画300ms,退场动画200ms,交互反馈100ms。
  • 插值器(Interpolator):控制动画的快慢节奏。比如LinearInterpolator是匀速,AccelerateDecelerateInterpolator是两头慢中间快。我建议:不要用匀速,太生硬了。
  • 重复行为(Repeat):动画是否重复、重复几次、是否反向。比如加载中的旋转动画,一般设置无限重复。

你想想看,这三个要素组合起来,就能产生千变万化的动画效果。比如一个按钮点击后的反馈:100ms的缩放动画,配合OvershootInterpolator,会有一个“弹一下”的效果,用户会觉得这个按钮很有“弹性”。

1.6 本章知识体系总览

下面我用一张图来总结本章的核心内容。这张图展示了Android动画体系的整体结构,以及View动画和Compose动画在其中的位置。

Android动画体系总览 动画本质:属性值 × 时间函数 × 帧率 View动画(补间动画) 属性动画 Compose动画 特点 • 仅4种属性 • 不改变真实位置 特点 • 任意属性可动 • 真实改变位置 特点 • 声明式编程 • 智能重组 核心三要素:时长(Duration) | 插值器(Interpolator) | 重复行为(Repeat)

这张图把整个体系串起来了。从底层的动画本质,到上层的三种实现方式,再到最核心的三要素。你记住这个结构,后面学起来就清晰了。

1.7 小结:这一章你该带走什么?

嗯,这一章的内容就到这里。我帮你梳理一下重点:

  • 动画的本质是属性随时间连续变化,帧率决定了流畅度,60fps是底线。
  • Android动画三驾马车:View动画(老但简单)、属性动画(中坚力量)、Compose动画(未来趋势)。
  • View动画和Compose动画的核心区别:命令式 vs 声明式,是否改变真实位置。
  • 三要素:时长、插值器、重复行为,掌握它们就能控制动画的节奏和效果。

下一章,我们会深入View动画的细节,看看那些经典的Animation类到底怎么用,以及我当年是怎么用错setFillAfter被测试追着打的。咱们下章见。


公众号:蓝海资料掘金营,微信deep3321