Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【云+社区年度征文】图解 AnimatedWidget 和 AnimatedBuilder 动画应用

【云+社区年度征文】图解 AnimatedWidget 和 AnimatedBuilder 动画应用

原创
作者头像
阿策小和尚
修改于 2020-12-16 02:02:04
修改于 2020-12-16 02:02:04
6230
举报
文章被收录于专栏:阿策小和尚阿策小和尚

     糟糕的 2020 年即将过去,今年发生了很多意想不到的事,无论如何,生活还要继续,努力朝着明天出发;今天和尚就简单回顾一下 2020 年自己关于技术的这点事儿,然后继续按计划学习;

     突如起来的疫情打乱的工作的节奏,有大半年的时间都是在家里远程办公,无论是生活还是工作多多少少都会有所影响;虽然在家里办公与同事小伙伴交流开会有所不便,但也有部分优点,免去了在北京来回上下班的两个小时,可以利用这段时间更好的休息和学习;

坚持 & 积累

     和尚自 2018 年开启了个人公众号后,坚持每周更新一篇原创文章,虽然都是一些小知识点,但是坚持了两年多,还是颇有收获,除了个人技术有所沉淀之外,还认识了很多一起搞技术的朋友,有了更多的交流;之后在【云+社区】增加了文章的曝光同时,还认识了很多坚持写作的大佬,甚至有一些是自己平常学习博客的大佬,获益良多;再之后陆续参加了【云+社区】的各类活动,包括个人阅读清单等,增加了学习的动力,希望努力和坚持会有所回报;

     和尚继续上一节中自定义的 ACEPageMenu 滑动菜单,详细介绍一下涉及到的 AnimatedBuilder 动画,在此之前需要先了解 AnimatedWidget

AnimatedWidget

     AnimatedWidget 是一个有状态的 StatefulWidget 小部件,通过指定 Listenable 更改值时重建小部件;AnimatedWidget 对于无状态的窗口小部件比较实用;含有众多子类动画,和尚会在之后的博客中慢慢学习;

源码分析
代码语言:txt
AI代码解释
复制
abstract class AnimatedWidget extends StatefulWidget {
  const AnimatedWidget({
    Key key,
    @required this.listenable,
  }) : super(key: key);

  final Listenable listenable;

  @protected
  Widget build(BuildContext context);

  @override
  _AnimatedState createState() => _AnimatedState();

  @override
  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
    super.debugFillProperties(properties);
    properties.add(DiagnosticsProperty<Listenable>('animation', listenable));
  }
}

     分析源码可得,AnimatedWidget 主要通过 Listenable 来监听小部件动画,通常是 AnimationChangeNotifier;通过重写 build() 方法来设置动画过程;并在 _AnimatedState 中设置状态的更新 setState()

     由此可见,AnimatedWidget 已封装好 setState() 状态更新模块,允许将调用中的动画代码中分离出 Widget,而无需单独维护一个 State 状态来保存动画;

案例尝试

     和尚尝试 AnimatedWidget 方式展示一个类似 ACEPageMenu 从顶部滑出的一个小动画效果;

代码语言:txt
AI代码解释
复制
class TopMenuWidget extends AnimatedWidget {
  const TopMenuWidget({Key key, AnimationController controller}) : super(key: key, listenable: controller);

  Animation<double> get _progress => listenable;

  @override
  Widget build(BuildContext context) {
    return Transform.translate(
        offset: Offset(50, 100 * _progress.value),
        child: Opacity(
            opacity: _progress.value,
            child: Container(
                width: 300.0, height: 100.0,
                color: Colors.yellow,
                child: Center(
                    child: GestureDetector(
                        onTap: () => print('I am from AnimatedWidget !'),
                        child: Icon(Icons.ac_unit, color: Colors.white))))));
  }
}

AnimatedBuilder

      AnimatedBuilder 也是用于构建动画的通用 Widget,是渲染树中的一个独立的类,适用于要提取单独动画效果的较复杂的 Widget;可自动监听来自 Animation 对象的通知,无需手动调用 addListener()

源码分析
代码语言:txt
AI代码解释
复制
class AnimatedBuilder extends AnimatedWidget {
  const AnimatedBuilder({
    Key key,
    @required Listenable animation,
    @required this.builder,
    this.child,
  }) : super(key: key, listenable: animation);

  final TransitionBuilder builder;
  final Widget child;

  @override
  Widget build(BuildContext context) {
    return builder(context, child);
  }
}

typedef TransitionBuilder = Widget Function(BuildContext context, Widget child);

      分析源码可得,AnimatedBuilder 继承自 AnimatedWidget,只需构造窗口小部件并将其传递给构建器函数即可;其中 TransitionBuilder 在每次动画更改值时调用;其中 child 比较特殊,可以作为优化的方向;

      如果 builder 函数包含一个不依赖于动画的子树,则一次构建该子树比在每个动画变更时都重新构建子树更为高效;即在 child 中预先定义好 WidgetAnimatedBuilder 会将其传递到构造器函数中;

案例尝试

     和尚尝试 AnimatedBuilder 方式展示一个类似 ACEPageMenu 从底部滑出的一个小动画效果;

代码语言:txt
AI代码解释
复制
return AnimatedBuilder(
    animation: _controller,
    child: Container(
        color: Colors.brown,
        height: 100.0, width: 300.0,
        child: Center(
            child: GestureDetector(
                onTap: () => print('I am form AnimatedBuilder !'),
                child: Icon(Icons.ac_unit, color: Colors.white)))),
    builder: (BuildContext context, Widget child) {
      return Transform.translate(
          offset: Offset(50, ScreenUtils.getScreenHeight() - _controller.value * 200),
          child: Opacity(opacity: _controller.value, child: child));
    });

     条条大路通罗马,同一效果可以有多种不同的实现方式;AnimatedWidgetAnimatedBuilder 使用都很便利,而和尚认为 AnimatedBuilder 在处理复杂动画时更加灵活方便;

注意事项

      和尚在尝试缩放动画过程中,遇到之前不曾注意的地方,即动画起始位置由 originalignment 共同决定,以 aligment 对齐位置为坐标原点,origin 在此基础上平移起始位置;与 scale 无关;

代码语言:txt
AI代码解释
复制
Transform.scale({
    Key key,
    @required double scale,
    this.origin,
    this.alignment = Alignment.center,
    this.transformHitTests = true,
    Widget child,
})

      和尚尝试了几个基本场景:

a. alignment 对齐方式默认居中,origin 起始位置默认为 Offset.zero 时,scale 增大为 1.5 倍;可以看到其初始动画位置仍为 Widget 缩放前的中心位;

代码语言:txt
AI代码解释
复制
return Transform.scale(
    scale: _progress.value * 1.5,
    origin: Offset.zero,
    alignment: Alignment.center,
    child: Container(width: 200.0, height: 200.0, color: Colors.yellow.withOpacity(0.8)));

b. alignment 对齐方式默认居中,调整 origin 起始位置为 Offset(50, 50);可以看到其初始动画位置是以 alignment 居中点为原点,水平竖直方向为坐标系轴,平移 origin 位置;

代码语言:txt
AI代码解释
复制
return Transform.scale(
    scale: _progress.value,
    origin: Offset(50, 50),
    alignment: Alignment.center,
    child: Container(width: 200.0, height: 200.0, color: Colors.yellow.withOpacity(0.8)));

c. alignment 默认居中右对齐,origin 起始位置为 Offset(50, 50);可以看到其初始动画位置是以 alignment 居中右对齐中点为原点,水平竖直方向为坐标系轴,平移 origin 位置;

代码语言:txt
AI代码解释
复制
return Transform.scale(
    scale: _progress.value,
    origin: Offset(50, 50),
    alignment: Alignment.centerRight,
    child: Container(width: 200.0, height: 200.0, color: Colors.yellow.withOpacity(0.8)));
````代码`

      AnimatedWidget 和 AnimatedBuilder 案例源码


      和尚对动画的源码还不够深入,如有错误,请多多指导!

来源: 阿策小和尚

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【日志服务CLS】初识腾讯 CLS 高速检索与 Nginx 预报警服务~
和尚虽然是移动端开发,但对于 Nginx 负载均衡稍稍有些了解,而曾经的毕业论文就是以 Nginx 为研究方向进行的,今天根据 腾讯云+社区 活动,简单尝试一下 Nginx 日志服务;
阿策小和尚
2021/05/18
1.3K1
【云+社区年度征文】从零开始搭建一个SpringBoot应用并成功上云
相信大家都具有在本地编写项目的丰富经验,然而本地的单击项目始终不能满足我们的需求,为此,本篇文章将介绍如何编写一个SpringBoot应用并成功将其部署到云服务器上。
wangweijun
2020/11/25
6880
【云+社区年度征文】小程序·云开发综合提升篇
什么是小程序云开发,从前端解决后端的活。18 年以为很多大公司减员,小公司关闭,到底是互联网的寒冬时期,还是互联网换新时期,我认为是后者。小程序开发周期一般都相对比比较短,如果一个企业还是一个团队去开发一个博客、资讯、新闻这类的产品,支出的成本是还是相对大比较大的。其中可能大部分时间我们都用在联调这个事上了,代码的测试,数据校验,很大时间浪费在前后端相互对接等待等。像小程序这种无服务在以后会越来越多,只管写接口、写逻辑就好。总得来说,虽然你管的东西越来越少,但开发效率却越来越高,开发出来的轻应用、小程序却是具备高性能、高可用、高扩展的特性, 开发人员的较少必定资金和人力的需求可谓大大节省。
山间木匠
2020/12/02
1.2K0
【云+社区年度征文】小程序·云开发综合提升篇
Ichunqiu云境 - Delegation Writeup
0x1 Info图片0x2 ReconTarget external IP39.98.34.149Nmap results图片关注80端口的http服务,目录爆破(省略)找到 /admin 图片使用弱口令登录进入后台,去到模板页面,编辑header.html,添加php一句话`用户名: admin, 密码:123456![f71dd2cf6322f6235561582fe3698a6.png](https://ask8088-private-1251520898.cn-south.myqcloud.com/
Gcow安全团队
2022/12/10
5110
【玩转腾讯云】用eclipse跑通腾讯云JavaSDK
https://www.oracle.com/java/technologies/javase-jdk13-downloads.html
大大大黑白格子
2020/03/27
17.6K0
【玩转腾讯云】用eclipse跑通腾讯云JavaSDK
重磅!腾讯云轻量应用服务器免费升配又双叒来了!
首先前往轻量应用服务器控制台查看机型https://console.cloud.tencent.com/lighthouse/instance/
小宇-xiaoyu
2022/03/04
3.5K0
【技术创作101训练营】- 前后端分离模式下如何保证开发人员不打架?
上传ppt很多颜色被改变了,如果评委老师想看原版的话,可以看pdf,麻烦了,谢谢。
手撕代码八百里
2021/01/20
1.1K3
【技术创作101训练营】- 前后端分离模式下如何保证开发人员不打架?
远程修改ESXi 6.7管理IP地址
2.使用SecureCRT SSH2连接ESXi主机,现在使用dcui并没有任何反应,在Session标签栏右键点击Disconnect。
donkexu
2021/06/23
8.8K0
远程修改ESXi 6.7管理IP地址
技术分享 | Bug定位方法
通常情况下 Bug 分为四个类型,分别是功能、性能、安全和专项质量。功能级别关注于业务流程是否正确。性能级别关注于业务流程是否顺畅。安全方面判断是否存在漏洞,是否符合安全标准与规范。专项质量通常关注于用户体验 UX、兼容性、稳定性和可靠性。
霍格沃兹测试开发
2022/03/29
3360
MySQL 索引(下)
从结果中看出,索引失效了,这是因为我们需要把索引字段的值都取出来,然后依次进行表达式的计算来进行条件判断,因此采用的就是全表扫描的方式,运行时间也会慢好多。
mr.songw
2021/01/15
7180
MySQL 索引(下)
2021年度Leetcode算法类型高频题总结&(附答案解析)
昨晚逛了逛GitHub,无意中看到一位P8大佬的算法刷题笔记,感觉发现了宝藏!有些小伙伴可能已经发现了,但咱这里还是忍不住安利一波,怕有些小伙伴没有看到。
Java程序猿
2021/12/24
9960
2021年度Leetcode算法类型高频题总结&(附答案解析)
idea2020.2版本 svn 自定义忽略文件
https://blog.csdn.net/seven71111/article/details/105784821
bug专8
2021/01/26
7.2K0
【玩转腾讯云】导入镜像-Windows 2008 R2 Datacenter
【腾讯云】关于Windows Server 2008 R2 企业版 SP1 64位公共镜像下线通知
大大大黑白格子
2020/03/26
10.5K18
【玩转腾讯云】导入镜像-Windows 2008 R2 Datacenter
都2021年了还不会在CentOS7上使用pyenv搭建Django环境吗?
pyenv是一个forked自ruby社区的简单、低调、遵循UNIX哲学的Python环境管理工具, 它可以轻松切换全局解释器版本, 同时结合vitualenv插件可以方便的管理对应的包源.
查理不是猹
2021/12/17
5560
windows单机搭建k8s环境——部署ingress
ingress是k8s对外暴露服务的一种方式。当我们使用购买的公有云服务时,平台已经提供部署好的ingress,用户只需要添加挂载策略即可。
DifficultWork
2021/04/06
1.8K0
Redis 安装部署
测试下部署在本地 Docker 容器中的 Redis 服务器同时处理 10 万个并发请求的性能:
Action
2021/04/15
7820
Redis 安装部署
【5分钟玩转Lighthouse】搭建bitwardenrs一个好玩的密码网站
可参考这篇文章:轻量应用服务器 使用远程登录软件登录 Linux 实例-操作指南-文档中心-腾讯云-腾讯云 (tencent.com)
用户9673240
2022/05/05
1.2K0
【5分钟玩转Lighthouse】搭建bitwardenrs一个好玩的密码网站
Windows下安装Mycat
已管理员身份启动cmd,进入D:\mycat\bin目录,执行mycat install
Action
2021/09/18
2.2K0
【Flutter 专题】91 图解 Dart 单线程实现异步处理之 Future (二)
小菜前几天刚学习了 Future 实现异步操作的部分方法,主要包括构造方法和常用的静态方法;小菜今天继续学习 Future 其他知识和 async-await 方式实现异步操作;
阿策小和尚
2020/06/15
7630
【Flutter 专题】91 图解 Dart 单线程实现异步处理之 Future (二)
【技术创作101训练营】Java 并发编程基础
在线观看样式会丢失,上传了 pdf 版本,zip 中有 ppt 及 keynote 原件。
KIWI
2021/01/20
4340
【技术创作101训练营】Java 并发编程基础
推荐阅读
相关推荐
【日志服务CLS】初识腾讯 CLS 高速检索与 Nginx 预报警服务~
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档