【动画 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 的动画的效率更高。


目录
相关文章
|
8天前
|
前端开发
Flutter快速实现自定义折线图,支持数据改变过渡动画
Flutter快速实现自定义折线图,支持数据改变过渡动画
19 4
Flutter快速实现自定义折线图,支持数据改变过渡动画
|
1月前
Flutter-实现头像叠加动画效果
Flutter-实现头像叠加动画效果
24 0
|
1月前
Flutter-加载中动画
Flutter-加载中动画
16 0
|
1月前
Flutter-自定义表情雨下落动画
Flutter-自定义表情雨下落动画
15 0
|
1月前
Flutter-底部弹出框(Widget层级)
文章描述了如何在Flutter中使用DraggableScrollableSheet创建一个底部弹出框,同时保持其可手势滑动关闭。作者遇到问题并提出对原控件进行扩展,以支持头部和列表布局的滑动关闭功能。
70 0
|
1月前
Flutter-数字切换动画
Flutter-数字切换动画
11 0
|
1月前
|
开发者
Flutter 动画学习
Flutter 动画学习
|
2月前
Flutter StreamBuilder 实现局部刷新 Widget
Flutter StreamBuilder 实现局部刷新 Widget
22 0
|
3月前
|
数据库 Android开发
Android数据库框架-GreenDao入门,2024年最新flutter 页面跳转动画
Android数据库框架-GreenDao入门,2024年最新flutter 页面跳转动画
Android数据库框架-GreenDao入门,2024年最新flutter 页面跳转动画
|
3月前
|
Android开发
Flutter完整开发实战详解(六、 深入Widget原理),2024百度Android岗面试真题收录解析
Flutter完整开发实战详解(六、 深入Widget原理),2024百度Android岗面试真题收录解析