多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
# 实例:TurnBox 我们之前已经介绍过RotatedBox,但是它有两个缺点:一是只能将其子节点以90度的倍数旋转,二是当旋转的角度发生变化时,旋转角度更新过程没有动画。 本节我们将实现一个TurnBox,它可以以任意角度来旋转其子节点,并且在角度发生变化时可以执行一个动画过渡到新状态,同时,我们可以手动指定动画速度。 TurnBox的完整代码如下: ``` import 'package:flutter/widgets.dart'; 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; @override _TurnBoxState createState() => new _TurnBoxState(); } class _TurnBoxState extends State<TurnBox> with SingleTickerProviderStateMixin { AnimationController _controller; @override void initState() { super.initState(); _controller = new AnimationController( vsync: this, lowerBound: -double.infinity, upperBound: double.infinity ); _controller.value = widget.turns; } @override void dispose() { _controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return RotationTransition( turns: _controller, child: widget.child, ); } @override void didUpdateWidget(TurnBox oldWidget) { super.didUpdateWidget(oldWidget); //旋转角度发生变化时执行过渡动画 if (oldWidget.turns != widget.turns) { _controller.animateTo( widget.turns, duration: Duration(milliseconds: widget.speed??200), curve: Curves.easeOut, ); } } } ``` 代码比较简单,我们主要是通过包装(组合)RotationTransition来实现的。 下面我们测试一下TurnBox的功能,测试代码如下: ``` import 'package:flutter/material.dart'; import '../widgets/index.dart'; class TurnBoxRoute extends StatefulWidget { @override _TurnBoxRouteState createState() => new _TurnBoxRouteState(); } class _TurnBoxRouteState extends State<TurnBoxRoute> { double _turns = .0; @override Widget build(BuildContext context) { return Center( child: Column( children: <Widget>[ TurnBox( turns: _turns, speed: 500, child: Icon(Icons.refresh, size: 50,), ), TurnBox( turns: _turns, speed: 1000, child: Icon(Icons.refresh, size: 150.0,), ), RaisedButton( child: Text("顺时针旋转1/5圈"), onPressed: () { setState(() { _turns += .2; }); }, ), RaisedButton( child: Text("逆时针旋转1/5圈"), onPressed: () { setState(() { _turns -= .2; }); }, ) ], ), ); } } ``` 测试代码运行后效果如下图: ![](https://box.kancloud.cn/2a9ed156722db9716a477e0b216959c8_360x640.png) 当我们点击旋转按钮时,两个图标的旋转都会旋转1/5圈,但旋转的速度是不同的,读者可以自己运行一下示例看看效果。