优美的应用体验 来自于细节的处理,更源自于码农的自我要求与努力,当然也需要码农年轻灵活的思维,不局限于思维,不局限语言限制,才是编程的最高境界。
本文章实现的效果如下图所示:

在这里定义一个Timer计时器来实现数字的自增,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | class Example629 extends StatefulWidget {<!-- --> @override _PageState createState() => _PageState(); } ? class _PageState extends State with TickerProviderStateMixin {<!-- --> //计时器 Timer _timer; ? //计时更新的次数 文本显示内容 int _count = 1000; ? //点击按钮时启动 void startTimer() {<!-- --> if (_timer != null && _timer.isActive) {<!-- --> stopTimer(); } _timer = Timer.periodic(Duration(milliseconds: 2000), (timer) {<!-- --> _count++; setState(() {<!-- -->}); }); } ? //点击停止按钮时停止计时 //Widget销毁时调用 void stopTimer() {<!-- --> _timer.cancel(); } ? @override void dispose() {<!-- --> super.dispose(); stopTimer(); } ... ... } |
显示页面的主体使用脚手架Scaffold来构建,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | @override Widget build(BuildContext context) {<!-- --> return Scaffold( backgroundColor: Colors.grey, appBar: AppBar( title: Text("AnimatedSwitcher 动画 "), ), //线性排列 body: Column( children: [ //第一部分 效果区域 Container( height: 180, width: MediaQuery.of(context).size.width, color: Colors.white, child: buildAnimatedSwitcher(context), ), //第二部分 按钮区域 与代码清单 代码清单 6-29 中的一致 buildContainer() ], ), ); } |
页面整体使用Column线性排列,第一部分就是使用AnimatedSwitcher来切换显示数字文本的区域,也是本文章的核心功能,构建代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | ///lib/code/code6/example_629_AnimatedSwitcher.dart AnimatedSwitcher buildAnimatedSwitcher(BuildContext context) {<!-- --> return AnimatedSwitcher( //动画执行切换时间 duration: const Duration(milliseconds: 1000), //动画构建器 构建指定动画类型 //每次修改都会回调两次 移进时回调一次 移出时回调一次 transitionBuilder: (Widget child, Animation<double> animation) {<!-- --> //构建切换使用动画 return buildMultAnimation(animation, child); }, //执行动画的子 Widget //只有子 Widget 被切换时才会触发动画 child: Text( '$_count', //显示指定key,不同的key会被认为是不同的Text key: ValueKey<int>(_count), style: TextStyle( fontSize: 44, fontWeight: FontWeight.w500, color: getRandomColor(), ), ), ); } |
在这里组合了多个动画组件使用,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | SlideTransition buildMultAnimation( Animation<double> animation, Widget child) {<!-- --> //Text移进的平移动画 Offset startOffset = Offset(0.0, -1.2); Offset endOffset = Offset(0.0, 0.0); if (animation.status == AnimationStatus.completed) {<!-- --> //Text移出的平移动画 startOffset = Offset(0.0, 1.2); endOffset = Offset(0.0, 0.0); } print("animation.status ${animation.status}"); //这里的核心内容是 动画的相互嵌套使用 //执行平移动画 return SlideTransition( // 位置移动区分移动进入的Text 与 移动出去的Text position: Tween(begin: startOffset, end: endOffset).animate( CurvedAnimation( parent: animation, //跳动的动画曲线 curve: Curves.bounceOut, ), ), //透明度渐变动画 child: FadeTransition( // 透明度从 0.0-1.0 opacity: Tween(begin: 0.0, end: 1.0).animate( CurvedAnimation( parent: animation, curve: Curves.linear, ), ), //绽放动画 child: ScaleTransition( scale: Tween(begin: 0.6, end: 1.0).animate( CurvedAnimation( parent: animation, curve: Curves.linear, ), ), child: child, ), ), ); } |
在这里也使用到了随机颜色的生成,代码如下:
1 2 3 4 | Color getRandomColor() {<!-- --> return Color.fromRGBO( Random().nextInt(256), Random().nextInt(256), Random().nextInt(256), 1); } |
页面中的第二部分就是按钮控制区域的构建,通过线性布局Row来左右排列两个按钮,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | Container buildContainer() {<!-- --> return Container( margin: EdgeInsets.only(top: 10), child: Row( //子Widget居中 mainAxisAlignment: MainAxisAlignment.center, children: [ ElevatedButton( child: Text("开始"), onPressed: () {<!-- --> startTimer(); }, ), SizedBox( width: 22, ), ElevatedButton( child: Text("停止"), onPressed: () {<!-- --> stopTimer(); }, ), ], ), ); } |
【x1】微信公众号的每日提醒 随时随记 每日积累 随心而过 文章底部扫码关注
【x2】各种系列的视频教程 免费开源 关注 你不会迷路
【x3】系列文章 百万 Demo 随时 复制粘贴 使用
【x4】简短的视频不一样的体验
【x5】必须有源码
<iframex id="qT3ctugT-1605609722496" src="//i2.wp.com/player.bilibili.com/player.html?aid=755342895" allowfullscreen="true" data-mediaembed="bilibili"></iframex>
Flutter 高级动画 实现数字的翻滚切换
不局限于思维,不局限语言限制,才是编程的最高境界。
以小编的性格,肯定是要录制一套视频的,随后会上传
有兴趣 你可以关注一下 西瓜视频 — 早起的年轻人
