【动画 widget】Flutter AnimatedSize

简介: 【动画 widget】Flutter AnimatedSize

image.png


刚看到这个 widget 的时候,有点奇怪,已经有了 AnimatedWidgetImplicitlyAnimatedWidget,感觉已经无所不能了啊,怎么还有个 AnimatedSize。存在肯定有他的价值,让我们来一探究竟吧。

可以这样给 AnimatedSize 下定义:一个有动画能力的布局 widget。AnimatedSize 和 AnimatedWidgetImplicitlyAnimatedWidget 相比,是完全不同的 widget。AnimatedSize 的动画是在 renderObject  实现的,效率更高。动画是由 child 驱动的,而不是由外界通过参数指定。

动画能力是附加的,本质上 AnimateSize 是一个布局 widget,所以第一步,按布局三板斧来研究。我们通过查看源码来研究下 child 的 constrains,AnimatedSize 的 size 和摆放 child

child 的 constrains

void performLayout() {
    _lastValue = _controller.value;
    _hasVisualOverflow = false;
    final BoxConstraints constraints = this.constraints;
    if (child == null || constraints.isTight) {
      _controller.stop();
      size = _sizeTween.begin = _sizeTween.end = constraints.smallest;
      _state = RenderAnimatedSizeState.start;
      child?.layout(constraints);
      return;
    }
    child!.layout(constraints, parentUsesSize: true);
    ... 后面省略
复制代码

在把 constrains 赋值给child 之前, AnimatedSize 并没有对 constrains 做修改,直接透传给了chid

AnimatedSize 的 size

  1. constrains  是 tight,size = constraints.smallest。
  2. constrains  是 loose, size 在 constrains 范围内取 childSize 的大小。

如果 childSize 发生变化引发了动画, size 在 constrains 的范围取 _animatedSize

_animatedSize 也就是动画过程中某一时间点上的值。

Size? get _animatedSize {
    return _sizeTween.evaluate(_animation);
  }
复制代码

摆放  child

只有 size 和 childSize 不一样的时候才能摆放 child。

只有一个情况下 size 比 childSize 大。当 child size 从大变小的时候,child 是直接没有过渡的直接变小,AnimatedSize 要执行动画,所以是慢慢变小,这个时候就会出现 size 比 childSize 大的情况。

如何摆放 child 是 alignment 参数控制的。

使用 AnimatedSize

百说不如一练。我们看一个例子。就是一个简单的 box,点击它会变大变小。


image.png

double _size = 250.0;
bool _large = false;
void _updateSize() {
  setState(() {
    _size = _large ? 250.0 : 100.0;
    _large = !_large;
  });
}
复制代码
Center(
  child: GestureDetector(
      onTap: () => _updateSize(),
      child: Container(
        color: Colors.amberAccent,
        child: AnimatedSize(
            alignment: Alignment.center,
            curve: Curves.easeIn,
            duration: const Duration(seconds: 1),
            child: Container(
              width: _size,
              height: _size,
              color: Colors.green,
            )),
      )))
复制代码

黄色代表 AnimatedSize size,绿色代表 childSize。你可能会有疑问,为什么变大的时候,child 和 parent 一起变大,而变小的时候,child 直接变小,而 parent 慢慢变小呢。其实这只是假象,真实情况都是 child 直接变大变小,parent 慢慢变大变小。变大的时候因为 AnimatedSize clip child ,把 child 裁剪了,所以感觉上好像和 AnimatedSize 一样大。

做个实验 加上 clipBehavior: Clip.none 看看效果,你会发现,变在的时候也是突然变大了。

AnimatedSize(
   // 加上这句
  clipBehavior: Clip.none,
...
复制代码

再试着修改下 alignemnt alignment: Alignment.center 改为alignment: Alignment.bottomRight,,效果如下


image.png

总之, AnimatedWidgetImplicitlyAnimatedWidget 的动画是由外面传参进行控制,而 AnimatedSize 是由内部分的 child 的 size 的变化引发动画过程,AnimatedSize 的动画的效率更高。


目录
相关文章
|
2天前
|
容器
Flutter Widget 解析
Flutter Widget 解析
|
2天前
|
存储 容器
Flutter 有状态Widget 和 无状态Widget
Flutter 有状态Widget 和 无状态Widget
|
1月前
深入理解Flutter鸿蒙next版本 中的Widget继承:使用extends获取数据与父类约束
本文详细介绍了Flutter中如何通过继承其他Widget来创建自定义组件。首先解释了Widget继承的基本概念,包括StatelessWidget和StatefulWidget的区别。接着通过具体示例展示了如何继承StatelessWidget和StatefulWidget,并在子类中访问父类的build方法和状态。最后,结合多个自定义Widget展示了如何在实际应用中灵活使用继承和组合来构建复杂的UI。
76 8
|
1月前
|
开发工具 UED 容器
Flutter&鸿蒙next 实现长按录音按钮及动画特效
本文介绍了如何在 Flutter 中实现一个带有动画效果的长按录音按钮。通过使用 `GestureDetector` 监听长按手势,结合 `AnimatedContainer` 和 `AnimationController` 实现按钮的动画效果,以及 `flutter_sound` 插件完成录音功能。文章详细讲解了功能需求、实现思路和代码实现,帮助读者逐步掌握这一实用功能的开发方法。
122 5
|
1月前
|
容器
flutter&鸿蒙next 使用 InheritedWidget 实现跨 Widget 传递状态
在 Flutter 中,状态管理至关重要。本文详细介绍了如何使用 InheritedWidget 实现跨 Widget 的状态传递。InheritedWidget 允许数据在 Widget 树中向下传递,适用于多层嵌套的场景。通过一个简单的计数器示例,展示了如何创建和使用 InheritedWidget,包括其基础概念、工作原理及代码实现。虽然 InheritedWidget 较底层,但它是许多高级状态管理解决方案的基础。
103 2
|
1月前
|
前端开发 开发者
深入探索 Flutter 鸿蒙版的画笔使用与高级自定义动画
本文深入探讨了 Flutter 中的绘图功能,重点介绍了 CustomPainter 和 Canvas 的使用方法。通过示例代码,详细讲解了如何绘制自定义图形、设置 Paint 对象的属性以及实现高级自定义动画。内容涵盖基本绘图、动画基础、渐变动画和路径动画,帮助读者掌握 Flutter 绘图与动画的核心技巧。
80 1
|
2月前
动画控制器在 Flutter 中的工作原理
【10月更文挑战第18天】总的来说,动画控制器 `AnimationController` 在 Flutter 中起着关键的作用,它通过控制动画的数值、速度、节奏和状态,实现了丰富多彩的动画效果。理解它的工作原理对于我们在 Flutter 中创建各种精彩的动画是非常重要的。
|
2月前
|
容器
flutter:第一个flutter&Widget的使用 (二)
本文介绍了Flutter框架下的基本组件及其用法,包括简单的 Stateless Widget 如文本和按钮,以及更复杂的 StatefulWidget 示例。详细解释了如何使用 `context` 获取祖先小部件的信息,并展示了 `MaterialApp` 的属性及用途。此外,还探讨了 `StatefulWidget` 与 `StatelessWidget` 的区别,以及 `AppBar` 的常见属性配置方法。适合Flutter初学者参考学习。
|
1月前
|
Dart JavaScript 前端开发
Flutter 的 Widget 概述与常用 Widgets 与鸿蒙 Next 的对比
Flutter 是 Google 开发的开源 UI 框架,用于快速构建高性能的移动、Web 和桌面应用。Flutter 通过 Widget 构建 UI,每个 UI 元素都是 Widget,包括文本、按钮、图片等。Widget 不仅描述外观,还描述行为,是不可变的。常见的 Widget 包括结构型(Container、Column、Row)、呈现型(Text、Image)、交互型(ElevatedButton)和状态管理型(StatefulWidget)。Flutter 与鸿蒙 Next 在组件化架构、开发语言、布局系统、性能和跨平台支持方面各有优势
75 0
|
2月前
|
UED
flutter:动画&状态管理 (十三)
本文档介绍了Flutter中`animatedList`的使用方法和状态管理的示例。`animatedList`用于创建带有动画效果的列表,示例代码展示了如何添加、删除列表项,并执行相应的动画效果。状态管理部分通过一个简单的点击切换颜色的示例,演示了如何在Flutter中管理组件的状态。