飞道的博客

Flutter AnimatedSwitcher 实现的滑动切换数字动画效果

526人阅读  评论(0)

优美的应用体验 来自于细节的处理,更源自于码农的自我要求与努力,当然也需要码农年轻灵活的思维,不局限于思维,不局限语言限制,才是编程的最高境界。

本文章实现的效果如下图所示:

在这里定义一个Timer计时器来实现数字的自增,代码如下:

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来构建,代码如下:

 @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来切换显示数字文本的区域,也是本文章的核心功能,构建代码如下:

  ///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(),
        ),
      ),
    );
  }

在这里组合了多个动画组件使用,代码如下:

  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,
        ),
      ),
    );
  }

在这里也使用到了随机颜色的生成,代码如下:


  Color getRandomColor() {
   
    return Color.fromRGBO(
        Random().nextInt(256), Random().nextInt(256), Random().nextInt(256), 1);
  }

页面中的第二部分就是按钮控制区域的构建,通过线性布局Row来左右排列两个按钮,代码如下:

 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】必须有源码


Flutter 高级动画 实现数字的翻滚切换


不局限于思维,不局限语言限制,才是编程的最高境界。

以小编的性格,肯定是要录制一套视频的,随后会上传

有兴趣 你可以关注一下 西瓜视频 — 早起的年轻人


转载:https://blog.csdn.net/zl18603543572/article/details/109749169
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场