Flutter: AnimatedContainer - свойства дочерних виджетов НЕ анимируются - PullRequest
0 голосов
/ 03 апреля 2019

У меня есть простой 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 не работает для дочерних виджетов, однако. Вам нужно изменить прямые свойства 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, который также способен оживить своих детей ?

1 Ответ

0 голосов
/ 03 апреля 2019

Нет волшебного виджета, который бы просто рекурсивно оживлял всех детей. Но я думаю, что вы хотите, это неявно анимированный виджет. то есть. вы изменяете параметры конструктора виджета, и при его изменении он анимируется от одного значения к другому.

Самый простой способ - это ImplicitlyAnimatedWidget с AnimatedWidgetBaseState. Так что для вашего примера для анимации атрибута 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 объекты для всех свойств, которые вы хотите анимировать.

...