Flutter 组件 | FadeTransition 透明变化
一、认识 FadeTransition 组件
1. FadeTransition 基本信息
FadeTransition
作为一个 SingleChildRenderObjectWidget
,说明其可以传入一个子组件,且需要承担 创建和更新 RenderObject
的任务。其功能是由 RenderAnimatedOpacity
对象完成。

2. FadeTransition 的使用
FadeTransition
需要一个 Animation
类型的参数 opacity
。也就是说,在使用时我们需要提供动画对象。如下让内容渐变出现,时长 2 s 。

class FadeTransitionTest extends StatefulWidget {
@override
_FadeTransitionTestState createState() => _FadeTransitionTestState();
}
class _FadeTransitionTestState extends State<FadeTransitionTest>
with SingleTickerProviderStateMixin {
AnimationController _opacity;
@override
void initState() {
super.initState();
_opacity = AnimationController(vsync: this, duration: Duration(seconds: 2))
..forward();
}
@override
void dispose() {
_opacity.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return FadeTransition(
opacity: _opacity,
child: buildContent(),
);
}
Widget buildContent() {
return Wrap(
direction: Axis.vertical,
alignment: WrapAlignment.center,
spacing: 10,
crossAxisAlignment: WrapCrossAlignment.center,
children: [
Image.asset(
'assets/images/icon_head.webp',
width: 80,
height: 80,
),
const Text('张风捷特烈',
style: TextStyle(fontSize: 16,fontWeight: FontWeight.bold),)
],
);
}
}
3.FadeTransition 的价值
在 Opacity
组件中,对 FadeTransition
的介绍是:它可以使用提供的 animation 进行高效的透明动画。与 FadeTransition
功能相似的是 AnimatedOpacity
,它内置动画器,使用者无须提供,用起来更方便。那为什么还要提供 FadeTransition
呢?

因为 FadeTransition
的动画对象由外界提供,操作起来更加灵活。 AnimatedOpacity
将其封装到内部,外界便无法访问。其实 AnimatedOpacity
组件本质就是对 FadeTransition
的一层封装,所以两者也没什么比较的必要, AnimatedOpacity
用起来更方便, FadeTransition
用起来更灵活,根据场景自行选择。

二、 FadeTransition 源码解读
1. FadeTransition 组件属性
最主要的属性是 Animation
型的 opacity
,当动画数值变化时,透明度会随之变化。

2. FadeTransition 维护的 RenderObject
作为 RenderObjectWidget
一族,有着创建和维护 RenderObject
的使命。 FadeTransition#createRenderObject
返回的是 RenderAnimatedOpacity
,也就是说透明动画的功能,是由该类实现的。

可以看出 FadeTransition
只是使用外界传入的属性创建 RenderAnimatedOpacity
,本身非常简单。下面继续看一下 RenderAnimatedOpacity
是如何实现 透明度跟随动画值变化
的。
三、 RenderAnimatedOpacity 源码解读
1. RenderAnimatedOpacity 类
RenderAnimatedOpacity
内只是对成员初始化了一下,什么都没处理。而是混入了 RenderAnimatedOpacityMixin
实现功能。
class RenderAnimatedOpacity extends RenderProxyBox with RenderProxyBoxMixin,
RenderAnimatedOpacityMixin<RenderBox> {
RenderAnimatedOpacity({
required Animation<double> opacity,
bool alwaysIncludeSemantics = false,
RenderBox? child,
}) : assert(opacity != null),
assert(alwaysIncludeSemantics != null),
super(child) {
this.opacity = opacity;
this.alwaysIncludeSemantics = alwaysIncludeSemantics;
}
}
2. Animation 对象被监听的时机
在 RenderAnimatedOpacityMixin.attach
方法中,会对 opacity
进行监听,也就是每当 opacity
的 value
变化时,会触发 _updateOpacity
方法。

在 RenderAnimatedOpacityMixin._updateOpacity
中,会通过 opacity
的值更新 _alpha
成员,并通过 markNeedsPaint
触发重绘。

3.RenderAnimatedOpacityMixin#paint 方法
如下是 RenderAnimatedOpacityMixin#paint
的逻辑,可见它和 RenderOpacity 的绘制是一样的。当 child
非空时,如果 _alpha = 0
就什么都不需要画。如果 _alpha = 255
,则直接绘制 child
。如果有透明度时,会通过 context.pushOpacity
添加 OpacityLayer
透明度层。

这样总的看来 FadeTransition
组件的功能实现还是比较简单的,就是通过监听 Animation
触发透明度更新和重绘。这些都是由 RenderAnimatedOpacity
自主完成的,动画执行的过程中,不涉及到其他 Elememnt
的重建,所以是比较高效的方式。那本文就到这里,谢谢观看 ~