flutter AnimatedSwitcher 动画切换过渡组件 跑马灯动画封装

news2024/10/7 11:32:47

flutter AnimatedSwitcher 动画切换过渡组件

  • 前言
  • 一、AnimatedSwitcher 简介
  • 二、AnimatedSwitcher 的简单使用
  • 三、AnimatedSwitcher 自定义跑马灯动画
  • 四、SlideTransitionX 的封装
  • 总结


前言

本篇文章将记录 AnimatedSwitcher 过渡组件,这个组件动画是一个新的小部件来代替另一个。它提供了一个很好的过渡,使应用程序非常流畅。始终为其子小部件添加一个键以确保其正常工作。


一、AnimatedSwitcher 简介

AnimatedSwitcher 可以同时对其新、旧子元素添加显示、隐藏动画。也就是说在AnimatedSwitcher的子元素发生变化时,会对其旧元素和新元素做动画,我们先看看AnimatedSwitcher 的源码:

const AnimatedSwitcher({
  Key? key,
  this.child,
  required this.duration, // 新child显示动画时长
  this.reverseDuration,// 旧child隐藏的动画时长
  this.switchInCurve = Curves.linear, // 新child显示的动画曲线
  this.switchOutCurve = Curves.linear,// 旧child隐藏的动画曲线
  this.transitionBuilder = AnimatedSwitcher.defaultTransitionBuilder, // 动画构建器
  this.layoutBuilder = AnimatedSwitcher.defaultLayoutBuilder, //布局构建器
})

当AnimatedSwitcher的 child 发生变化时(类型或 Key 不同),旧 child 会执行隐藏动画,新 child 会执行执行显示动画。究竟执行何种动画效果则由transitionBuilder参数决定,该参数接受一个AnimatedSwitcherTransitionBuilder类型的 builder,定义如下:

typedef AnimatedSwitcherTransitionBuilder =
  Widget Function(Widget child, Animation<double> animation);

关于AnimatedSwitcher 组件的介绍就到这里,具体的属性的使用,有兴趣的可以去私下尝试一下,下面我们先来一个简单的使用。

二、AnimatedSwitcher 的简单使用

我们先来实现一个计数器,然后在每一次自增的过程中,旧数字执行缩小动画隐藏,新数字执行放大动画显示,代码如下

 AnimatedSwitcher(
              duration: Duration(milliseconds: 1000), // 新child 显示时长
              reverseDuration: Duration(milliseconds: 500), // 旧child 显示时长
              // transitionBuilder 动画展示的样式,日常开发中,可以根据实际需要,来设置不同的样式
              transitionBuilder: (Widget child, Animation<double> animation){
                return ScaleTransition(scale: animation, child: child,);
              },
              child: Text(
                "${count}",
                // 显示指定key, 不同的key 会被认为是不同的text,不添加key,不会执行动画
                key: ValueKey(count),
                style: TextStyle(
                  color: Colors.blue,
                  fontSize: 32
                ),
              ),
            ),
            MaterialButton(
              onPressed: () {
                setState(() {
                  count += 1;
                });
              },
              child: Text("count+1"),
            ),

运行上面的代码,当你点击+1 的时候,数字会有一个旧数字缩小,新数字放大的一个展示

在这里插入图片描述

三、AnimatedSwitcher 自定义跑马灯动画

如果项目需求,需要我们的数据从右侧进来,左侧出去,那么我们现在就没法去实现了,如果需要实现,就需要我们去改造一下SlideTransition 组件,下面一起来看改造代码

class CustomSlideTransitionWidget extends AnimatedWidget {
  final Widget child;
  final bool transformHitTests;

  const CustomSlideTransitionWidget({
    Key? key,
    required Animation<Offset> position,
    required this.child,
    this.transformHitTests = true,
  }) : super(key: key, listenable: position);

  
  Widget build(BuildContext context) {
    final position = listenable as Animation<Offset>;
    Offset offset = position.value;
    if (position.status == AnimationStatus.reverse) {
      offset = Offset(-offset.dx, offset.dy);
    }

    return FractionalTranslation(
      translation: offset,
      transformHitTests: transformHitTests,
      child: child,
    );
  }
}

上面代码中,与SlideTransition唯一的不同就是对动画的反向执行进行了定制(从左边滑出隐藏),position.status == AnimationStatus.reverse

接下来我们来使用验证

AnimatedSwitcher(
              duration: Duration(milliseconds: 1000), // 新child 显示时长
              reverseDuration: Duration(milliseconds: 500), // 旧child 显示时长
              transitionBuilder: (Widget child, Animation<double> animation) {
                var tween =
                    Tween<Offset>(begin: Offset(1, 0), end: Offset(0, 0));
                return CustomSlideTransitionWidget(
                    position: tween.animate(animation), child: child);
              },
              child: Text(
                "${count}",
                // 显示指定key, 不同的key 会被认为是不同的text,不添加key,不会执行动画
                key: ValueKey(count),
                style: TextStyle(color: Colors.blue, fontSize: 32),
              ),
            ),

运行结果输出:

在这里插入图片描述

当我们点击+1 的时候,新的数字会从右侧出来,旧的数字会从左侧消失。

四、SlideTransitionX 的封装

其实本篇文章,到这里就已经写完了,但是如果我们需要实现“左入右出”、“上入下出”或者 “下入上出”怎么办?这样是不是每一种模式,都得去定义一个Transition,这样无形中会很麻烦,那么接下来,我们就来继续改造一下CustomSlideTransitionWidget 组件,把上面说的都封装进去

class CustomSlideTransitionWidget extends AnimatedWidget {
  final Widget child;
  final bool transformHitTests;
  final AxisDirection direction;
  late Tween<Offset> _tween;

  CustomSlideTransitionWidget({
    Key? key,
    required Animation<double> position,
    required this.child,
    this.transformHitTests = true,
    this.direction = AxisDirection.down,
  }) : super(key: key, listenable: position) {
    switch (direction) {
      case AxisDirection.up:
        _tween = Tween(begin: const Offset(0, 1), end: const Offset(0, 0));
        break;
      case AxisDirection.right:
        _tween = Tween(begin: const Offset(-1, 0), end: const Offset(0, 0));

        break;
      case AxisDirection.down:
        _tween = Tween(begin: const Offset(0, -1), end: const Offset(0, 0));

        break;
      case AxisDirection.left:
        _tween = Tween(begin: const Offset(1, 0), end: const Offset(0, 0));

        break;
    }
  }

  
  Widget build(BuildContext context) {
    final position = listenable as Animation<double>;
    Offset offset = _tween.evaluate(position);

    if (position.status == AnimationStatus.reverse) {
      switch (direction) {
        case AxisDirection.up:
          offset = Offset(offset.dx, -offset.dy);
          break;
        case AxisDirection.right:
          offset = Offset(-offset.dx, offset.dy);
          break;
        case AxisDirection.down:
          offset = Offset(offset.dx, -offset.dy);
          break;
        case AxisDirection.left:
          offset = Offset(-offset.dx, offset.dy);
          break;
      }
    }

    return FractionalTranslation(
      translation: offset,
      transformHitTests: transformHitTests,
      child: child,
    );
  }
}

使用方法

AnimatedSwitcher(
              duration: Duration(milliseconds: 1000), // 新child 显示时长
              reverseDuration: Duration(milliseconds: 500), // 旧child 显示时长
              transitionBuilder: (Widget child, Animation<double> animation) {
                return CustomSlideTransitionWidget(
                  position: animation,
                  // 上入下出
                  direction: AxisDirection.down,
                  child: child,
                );
              },
              child: Text(
                "${count}",
                // 显示指定key, 不同的key 会被认为是不同的text,不添加key,不会执行动画
                key: ValueKey(count),
                style: TextStyle(color: Colors.blue, fontSize: 32),
              ),
            ),

在使用的时候,我们只需要选择一个direction 就可以了

运行效果如下:
请添加图片描述


总结

本篇文章不仅记录了AnimatedSwitcher的详细用法,同时也介绍了打破AnimatedSwitcher动画对称性的方法。然后经过我们自己的封装改造,AnimatedSwitcher 在日常开发过程中,将十分的受用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/25251.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

制作一个简单HTML宠物猫网页(HTML+CSS)

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

在 Spring Boot中配置日志

Spring Boot 在引擎盖下使用Apache Commons Logging。但是&#xff0c;它允许您选择所需的日志记录库。让我们来看看使用 Spring Boot 时的一些配置和最佳实践。 目录 概述简单日志记录示例配置日志记录 更改日志级别将日志写入文件在 Spring 引导中更改日志记录模式对日志条…

基于小波域的隐马尔可夫树模型的图像去噪方法的matlab实现代码

目录 1.算法概述 2.仿真效果预览 3.MATLAB部分代码预览 4.完整MATLAB程序 1.算法概述 为适应图像的空域非平稳变化, 提出了一种基于小波域分类隐马尔可夫树(CHMT)模型的图像去噪方法.该模型中,图像在每一尺度每一子带的小波系数均被分成C组以突出其空域非平稳变化 的特征,这…

MySQL有哪些锁

这次&#xff0c;来说说 MySQL 的锁&#xff0c;主要是 Q&A 的形式&#xff0c;看起来会比较轻松。 在 MySQL 里&#xff0c;根据加锁的范围&#xff0c;可以分为全局锁、表级锁和行锁三类。 全局锁 全局锁是怎么用的&#xff1f; 要使用全局锁&#xff0c;则要执行这条命…

彻底搞明白概率论:事件间的关系与运算;频率与概率

文章目录事件间的关系事件间的运算事件间的运算法则概率描述性定义统计性定义频率频率的性质频率是否能够作为概率呢&#xff1f;公理化定义概率的重要性质事件间的关系 注意互斥关系和对立关系&#xff1a; 互斥关系是&#xff1a;只要 A,BA,BA,B 不同时发生&#xff08;不存在…

山东菏泽家乡网页代码 html静态网页设计制作 dw静态网页成品模板素材网页 web前端网页设计与制作 div静态网页设计

家乡旅游景点网页作业制作 网页代码运用了DIV盒子的使用方法&#xff0c;如盒子的嵌套、浮动、margin、border、background等属性的使用&#xff0c;外部大盒子设定居中&#xff0c;内部左中右布局&#xff0c;下方横向浮动排列&#xff0c;大学学习的前端知识点和布局方式都有…

MindFusion JavaScript R2 套件 Crack

MindFusion JavaScript R2将您的 JAVASCRIPT 应用程序更快地推向市场 MindFusion JavaScript 库旨在显着缩短开发任何类型的交互式 JS 应用程序所需的时间。它们还使开发更加容易。 用于 JavaScript 的 MindFusion 包 JavaScript 数据视图 数据网格JavaScript 图 绘图JavaScr…

DJYGUI系列文章八:GDD绘图系统

目录 1 GDD绘图系统概述 1.1绘图上下文 1.2 DrawColor&#xff0c;FillColor&#xff0c;TextColor的作用与区别 2 API说明 2.1 SetRopCode&#xff1a; 设置当前光栅码 2.2 GetRopCode&#xff1a; 获得当前光栅码 2.3 MoveTo&#xff1a; 设置当前坐标位置 2.4 SetDr…

Web基础习题

1.语义化标签 1.现需要设置一个按钮&#xff0c;请填写语义化标签补全代码片段&#xff08;仅填写一个标签名即可&#xff09; <_____>点我!</_____> 2.在HTML中一般用哪个语义化标签表示斜体文本效果 3.在HTML中一般用哪个语义化标签表示头部导航 4.在HTML中一…

web前端-html-css-字体(字体的样式,字体的分类,字体其他样式,字体简写样式,文本样式)

字体的样式 <!DOCTYPE html> <html><head><meta charset"utf-8" /><title></title><style type"text/css">.p1 {font-size: 30px;font-family: "curlz mt";}</style></head><body>…

vite+ts前期准备(尽量详细在更新)

创建和准备vitets项目 打开命令行或进入vscode打开终端 输入命令:npm init vite 选择vuets cd 进入项目 cnpm/yarn/npm install 初次运行项目 终端输入命令:cnpm run dev 可以设置运行之后自动打开浏览器 目录打开package.json dev:vite --open 添加–open 查看环境变量 目录打…

Latex IEEE模板导入中文问题

IEEE模板下载 下载IEEE的conference的latex模板文件&#xff1a; conference&#xff1a;https://www.ieee.org/conferences/publishing/templates.html 模板包括以下文件 编译 IEEE模板需要用pdflatex编译&#xff0c;否则英文的粗体等无法正常显示。 使用pdflatex编译 …

select......for update会锁表还是锁行?

select查询语句是不会加锁的&#xff0c;但是select .......for update除了有查询的作用外&#xff0c;还会加锁呢&#xff0c;而且它是悲观锁。 那么它加的是行锁还是表锁&#xff0c;这就要看是不是用了索引/主键。 没用索引/主键的话就是表锁&#xff0c;否则就是是行锁。…

Flutter组件--TabBar使用详情(分段控制器)

TabBar介绍 一个显示水平行选项卡的Widget。 通常创建为 AppBar 的 AppBar.bottom 部分并与 TabBarView 结合使用 在什么情况下使用TabBar 当你的app内容类别比较多的时候&#xff0c;我们常常会用到TabBar&#xff0c;例如网易新闻、京东、B站等&#xff0c;所以TabBar是一…

CentOS7 设置 MySQL 主备同步

文章目录环境准备修改配置文件创建同步数据账户设置主库信息测试参考资料本文主要介绍在 MySQL 的主备同步设置方法。环境准备 Linux&#xff1a;Centos 7 MySQL&#xff1a;5.7 主节点&#xff1a;192.168.210.18 备节点&#xff1a;192.168.210.19 主备节点 MySQL 均支持…

2022 Android 高级进阶学习资料与高频精选面试题精讲(圆梦大厂)

序言 可能每个技术人都有个大厂梦&#xff0c;我也不例外。最近准备跳槽&#xff0c;前一阵子在准备各种面试&#xff0c;也面了几个大厂&#xff0c;其中包括字节、阿里 就以字节面试为例&#xff0c;面试总共花费了 20 天左右&#xff0c;包含了 4 轮电话面试、1 轮笔试、1 轮…

锐捷OSPF基础实验配置

目录 配置基础的邻居建立 配置Area4的虚链路 配置OSPF特殊区域 配置路由重分发 配置OSPF汇总 下发缺省路由 配置OSPF邻居认证 配置OSPF的网络类型 配置基础的邻居建立 以R1和R2建立邻居为例子&#xff08;其余设备邻居建立配置相同&#xff09; R1配置 int g0/0 no swi…

安泰测试-矢量网络分析仪有哪些应用?

网络分析仪可用于表征射频(RF)器件。尽管最初只是测量 S 参数&#xff0c;但为了优于被测器件&#xff0c;现在的网络分析仪已经高度集成&#xff0c;并且非常先进。 射频电路需要独特的测试方法。在高频内很难直接测量电压和电流&#xff0c;因此在测量高频器件时&#xff0c…

电话语音控件:AddTapi.NET 6.0 Crack

关于 AddTapi.NET 轻松地将电话 (TAPI) 功能添加到您的 C#、VB.NET 或 C 应用程序。 AddTapi.NET 支持 Microsoft 电话应用程序编程接口 (TAPI) 1.3 - 3.1&#xff0c;并适用于所有与 TAPI 兼容的电话硬件&#xff0c;从语音调制解调器到高级电话板再到与 TAPI 兼容的 PBX 系统…

2.9 Python 流程控制

文章目录1. 流程控制2. 顺序结构3. 伪代码4. 流程图4.1 顺序结构4.2 分支结构4.3 多分支结构4.4 循环结构1. 流程控制 流程控制: 控制程序按照一定的结构进行执行. 流程控制指的是代码的运行逻辑, 分支走向, 循环控制, 能真正体现程序执行顺序的操作.* 1966年计算机科学家 C.B…