【问题标题】:Flutter: AnimatedContainer - children widgets' properties are NOT animatingFlutter:AnimatedContainer - 子小部件的属性没有动画
【发布时间】:2019-08-24 07:57:05
【问题描述】:

我有一个简单的AnimatedWidget,带有一个子小部件。

AnimatedContainer(
   duration: Duration(milliseconds: 2000),
   curve: Curves.bounceOut,
   decoration: BoxDecoration(
      color: Colors.purple,
   ),
   child: FlutterLogo(
     size: _boxSize,
   ),
),

_boxSize 的动画如下:

void _startAnimation() => setState(() {
    _boxSize *= 1.7;
  });
但是,

AnimatedContainer child 小部件不起作用。您需要更改 AnimatedContainer 的直接属性才能使动画正常工作。

这符合文档:

The [AnimatedContainer] will automatically animate between the old 
and new values of properties when they change using the provided curve 
and duration. Properties that are null are not animated. 
Its child and descendants are not animated.

AnimatedContainer等价物是什么,它也可以为其子级设置动画

【问题讨论】:

  • 您找到解决方案了吗?

标签: dart flutter flutter-animation


【解决方案1】:

很少有小部件可以为孩子设置动画。您可以使用 AnimatedSwitcher Widget 将新的颤振徽标小部件替换为首选大小。

  1. AnimatedSwitcher - 此小部件将用新小部件交换子小部件。
  2. AnimatedPositioned - 只要给定位置发生变化,它就会从堆栈小部件中更改子组件的位置。
  3. AnimatedAlign - align 的动画版本,只要给定的对齐方式发生变化,就会改变孩子的对齐方式。
  4. AnimatedCrossFade - 它在两个孩子之间逐渐消失,并在他们的大小之间进行动画处理。

【讨论】:

    【解决方案2】:

    没有神奇的小部件可以简单地递归地为所有孩子设置动画。但我认为你想要的是一个隐式动画小部件。 IE。您更改小部件的构造函数参数,并且随着它的更改,它会从一个值动画到下一个值。

    最简单的方法可能是ImplicitlyAnimatedWidgetAnimatedWidgetBaseState。因此,对于您的示例,动画 boxSize 属性可能如下所示:

    class AnimatedFlutterLogo extends ImplicitlyAnimatedWidget {
      const AnimatedFlutterLogo({Key key, @required this.boxSize, @required Duration duration})
          : super(key: key, duration: duration);
    
      final double boxSize;
    
      @override
      ImplicitlyAnimatedWidgetState<ImplicitlyAnimatedWidget> createState() => _AnimatedFlutterLogoState();
    }
    
    class _AnimatedFlutterLogoState extends AnimatedWidgetBaseState<AnimatedFlutterLogo> {
      Tween<double> _boxSize;
    
      @override
      void forEachTween(visitor) {
        _boxSize = visitor(_boxSize, widget.boxSize, (dynamic value) => Tween<double>(begin: value));
      }
    
      @override
      Widget build(BuildContext context) {
        return Container(
          child: FlutterLogo(
            size: _boxSize?.evaluate(animation),
          ),
        );
      }
    }
    

    恕我直言,这已经很简洁了,唯一真正的样板基本上是 forEachTween(visitor) 方法,它必须为您想要动画的所有属性创建 Tween 对象。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-09
      • 1970-01-01
      • 1970-01-01
      • 2020-09-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多