参考资料:《Flutter实战·第二版》 10.3 组合实例:TurnBox
这里尝试实现一个更为复杂的例子,其能够旋转子组件。Flutter中的RotatedBox
可以旋转子组件,但是它有两个缺点:
- 一是只能将其子节点以90度的倍数旋转
- 二是当旋转的角度发生变化时,旋转角度更新过程没有动画
因此,这里将自定义一个TurnBox,不仅可以设置任意角度旋转的子Widget,还能再角度发生改变时执行一个过渡动画,同时,还可以手动设置动画的执行时长。
首先,组件一定是一个动画组件,需要实现SingleTickerProviderStateMixin
并设置Controler对象,这里没有定义AnimationController对象,直接在Controler内部设置起始值,默认值是[0, 1],类型为浮点数。输入参数有旋转的多少、旋转动画的时长和子Widget,其具有默认的初始值。
在组件初始化阶段,首先定义_controller
,其取值范围为 [ − ∞ , + ∞ ] [-\infin,+\infin] [−∞,+∞],并将其初始值设为传入参数,否则为默认值0。
组件通过RotationTransition
构建,需传入一个Animation<double>
对象并设置子Widget。
当外部传入的参数turns
或speed
变化时(turns
为主要控制变量),则执行动画到目标状态。
注意在组件销毁的dispose()
函数当中销毁_controller
防止内存泄漏的问题。
class TurnBox extends StatefulWidget {
const TurnBox({
Key? key,
this.turns = .0, //旋转的“圈”数,一圈为360度,如0.25圈即90度
this.speed = 200, //过渡动画执行的总时长
this.child
}) :super(key: key);
final double turns;
final int speed;
final Widget? child;
TurnBoxState createState() => TurnBoxState();
}
class TurnBoxState extends State<TurnBox