forEachTween method

  1. @override
void forEachTween(
  1. TweenVisitor visitor
)
override

Visits each tween controlled by this state with the specified visitor function.

Subclass responsibility

Properties to be animated are represented by Tween member variables in the state. For each such tween, forEachTween implementations are expected to call visitor with the appropriate arguments and store the result back into the member variable. The arguments to visitor are as follows:

The tween argument should contain the current tween value. This will initially be null when the state is first initialized.

The targetValue argument should contain the value toward which the state is animating. For instance, if the state is animating its widget's opacity value, then this argument should contain the widget's current opacity value.

The constructor argument should contain a function that takes a value (the widget's value being animated) and returns a tween beginning at that value.

When this method will be called

forEachTween is initially called during initState. It is expected that the visitor's tween argument will be set to null, causing the visitor to call its constructor argument to construct the tween for the first time. The resulting tween will have its begin value set to the target value and will have its end value set to null. The animation will not be started.

When this state's widget is updated (thus triggering the didUpdateWidget method to be called), forEachTween will be called again to check if the target value has changed. If the target value has changed, signaling that the animation should start, then the visitor will update the tween's start and end values accordingly, and the animation will be started.

Other member variables

Subclasses that contain properties based on tweens created by forEachTween should override didUpdateTweens to update those properties. Dependent properties should not be updated within forEachTween.

{@tool snippet}

This sample implements an implicitly animated widget's State. The widget animates between colors whenever widget.targetColor changes.

class MyWidgetState extends AnimatedWidgetBaseState<MyWidget> {
  ColorTween? _colorTween;

  @override
  Widget build(BuildContext context) {
    return Text(
      'Hello World',
      // Computes the value of the text color at any given time.
      style: TextStyle(color: _colorTween?.evaluate(animation)),
    );
  }

  @override
  void forEachTween(TweenVisitor<dynamic> visitor) {
    // Update the tween using the provided visitor function.
    _colorTween = visitor(
      // The latest tween value. Can be `null`.
      _colorTween,
      // The color value toward which we are animating.
      widget.targetColor,
      // A function that takes a color value and returns a tween
      // beginning at that value.
      (dynamic value) => ColorTween(begin: value as Color?),
    ) as ColorTween?;

    // We could have more tweens than one by using the visitor
    // multiple times.
  }
}

{@end-tool}

Implementation

@override
void forEachTween(TweenVisitor<dynamic> visitor) {
  _tweenOffset = visitor(
    _tweenOffset,
    widget.offset,
    (dynamic value) => Tween<Offset>(begin: value),
  ) as Tween<Offset>?;

  _tweenScale = visitor(
    _tweenScale,
    widget.scale,
    (dynamic value) => Tween<double>(begin: value),
  ) as Tween<double>?;

  _tweenRotateZ = visitor(
    _tweenRotateZ,
    widget.rotate,
    (dynamic value) => Tween<double>(begin: value),
  ) as Tween<double>?;

  _tweenRotateX = visitor(
    _tweenRotateX,
    widget.flipY ? _pi : 0.0,
    (dynamic value) => Tween<double>(begin: value),
  ) as Tween<double>?;

  _tweenRotateY = visitor(
    _tweenRotateY,
    widget.flipX ? _pi : 0.0,
    (dynamic value) => Tween<double>(begin: value),
  ) as Tween<double>?;

  _tweenAlignment = visitor(
    _tweenAlignment,
    widget.alignment,
    (dynamic value) =>
        AlignmentGeometryTween(begin: value as AlignmentGeometry),
  ) as AlignmentGeometryTween?;
}