build method

  1. @override
Widget build(
  1. BuildContext context,
  2. Widget child,
  3. AnimationController controller,
  4. EffectEntry entry,
)
override

Builds the widgets necessary to implement the effect, based on the provided AnimationController and EffectEntry.

Implementation

@override
Widget build(
  BuildContext context,
  Widget child,
  AnimationController controller,
  EffectEntry entry,
) {
  // instead of setting up an animation, we can optimize a bit to calculate the callback time once:
  double ratio = getEndRatio(controller, entry);
  double prevVal = controller.value;
  AnimationStatus prevStatus = controller.status;
  controller.addListener(() {
    double val = controller.value;
    AnimationStatus status = controller.status;
    if (val == prevVal && status == prevStatus) return;

    if (!controller.isAnimating) {
      // adapter (probably!)
      _resolve(ratio, prevVal, val, callback);
    } else if (status == AnimationStatus.forward) {
      if (prevStatus == AnimationStatus.dismissed) {
        // just started (probably)
        _resolve(ratio, controller.lowerBound - 1, val, callback);
      } else if (prevStatus == AnimationStatus.reverse) {
        // repeated from reverse to forward (probably)
        _resolve(ratio, prevVal, controller.lowerBound, callback);
        _resolve(ratio, controller.lowerBound, val, callback);
      } else if (val < prevVal) {
        // repeated forward to forward (probably)
        _resolve(ratio, prevVal, controller.upperBound, callback);
        _resolve(ratio, controller.lowerBound - 1, val, callback);
      } else {
        // playing forward (probably)
        _resolve(ratio, prevVal, val, callback);
      }
    } else if (status == AnimationStatus.reverse) {
      if (prevStatus == AnimationStatus.dismissed) {
        // just started (probably)
        _resolve(ratio, controller.upperBound + 1, val, callback);
      } else if (prevStatus == AnimationStatus.forward) {
        // repeated from forward to reverse (probably)
        _resolve(ratio, prevVal, controller.upperBound, callback);
        _resolve(ratio, controller.upperBound, val, callback);
      } else if (val > prevVal) {
        // repeated reverse to reverse (probably)
        _resolve(ratio, prevVal, controller.lowerBound, callback);
        _resolve(ratio, controller.upperBound + 1, val, callback);
      } else {
        // playing in reverse (probably)
        _resolve(ratio, prevVal, val, callback);
      }
    }
    prevVal = val;
    prevStatus = status;
  });
  return child;
}