AnimationController class

A controller for an animation.

This class lets you perform tasks such as:

By default, an AnimationController linearly produces values that range from 0.0 to 1.0, during a given duration.

When the animation is actively animating, the animation controller generates a new value each time the device running your app is ready to display a new frame (typically, this rate is around 60–120 values per second). If the animation controller is associated with a State through a TickerProvider, then its updates will be silenced when that State's subtree is disabled as defined by TickerMode; time will still elapse, and methods like forward and stop can still be called and will change the value, but the controller will not generate new values on its own.

Ticker providers

An AnimationController needs a TickerProvider, which is configured using the vsync argument on the constructor. The constructor uses the TickerProvider to create a Ticker, which the AnimationController uses to step through the animation it controls.

For advice on obtaining a ticker provider, see TickerProvider. Typically the relevant State serves as the ticker provider, after applying a suitable mixin (like SingleTickerProviderStateMixin) to cause the State subclass to implement TickerProvider.

Life cycle

An AnimationController should be disposed when it is no longer needed. This reduces the likelihood of leaks. When used with a StatefulWidget, it is common for an AnimationController to be created in the State.initState method and then disposed in the State.dispose method.

Using Futures with AnimationController

The methods that start animations return a TickerFuture object which completes when the animation completes successfully, and never throws an error; if the animation is canceled, the future never completes. This object also has a TickerFuture.orCancel property which returns a future that completes when the animation completes successfully, and completes with an error when the animation is aborted.

This can be used to write code such as the fadeOutAndUpdateState method below.

Here is a stateful Foo widget. Its State uses the SingleTickerProviderStateMixin to implement the necessary TickerProvider, creating its controller in the State.initState method and disposing of it in the State.dispose method. The duration of the controller is configured from a property in the Foo widget; as that changes, the State.didUpdateWidget method is used to update the controller.
link
class Foo extends StatefulWidget {
  const Foo({ super.key, required this.duration });

  final Duration duration;

  @override
  State<Foo> createState() => _FooState();
}

class _FooState extends State<Foo> with SingleTickerProviderStateMixin {
  late AnimationController _controller;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      vsync: this, // the SingleTickerProviderStateMixin
      duration: widget.duration,
    );
  }

  @override
  void didUpdateWidget(Foo oldWidget) {
    super.didUpdateWidget(oldWidget);
    _controller.duration = widget.duration;
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Container(); // ...
  }
}

The following method (for a State subclass) drives two animation controllers using Dart's asynchronous syntax for awaiting Future objects:
link
Future<void> fadeOutAndUpdateState() async {
  try {
    await fadeAnimationController.forward().orCancel;
    await sizeAnimationController.forward().orCancel;
    setState(() {
      dismissed = true;
    });
  } on TickerCanceled {
    // the animation got canceled, probably because we were disposed
  }
}

The assumption in the code above is that the animation controllers are being disposed in the State subclass' override of the State.dispose method. Since disposing the controller cancels the animation (raising a TickerCanceled exception), the code here can skip verifying whether State.mounted is still true at each step. (Again, this assumes that the controllers are created in State.initState and disposed in State.dispose, as described in the previous section.)

This example shows how to use AnimationController and SlideTransition to create an animated digit like you might find on an old pinball machine our your car's odometer. New digit values slide into place from below, as the old value slides upwards and out of view. Taps that occur while the controller is already animating cause the controller's AnimationController.duration to be reduced so that the visuals don't fall behind.
link

To create a local project with this code sample, run:
flutter create --sample=animation.AnimationController.3 mysample

See also:

Inheritance
Mixed-in types

Constructors

AnimationController({double? value, Duration? duration, Duration? reverseDuration, String? debugLabel, double lowerBound = 0.0, double upperBound = 1.0, AnimationBehavior animationBehavior = AnimationBehavior.normal, required TickerProvider vsync})
Creates an animation controller.
AnimationController.unbounded({double value = 0.0, Duration? duration, Duration? reverseDuration, String? debugLabel, required TickerProvider vsync, AnimationBehavior animationBehavior = AnimationBehavior.preserve})
Creates an animation controller with no upper or lower bound for its value.

Properties

animationBehavior AnimationBehavior
The behavior of the controller when AccessibilityFeatures.disableAnimations is true.
final
debugLabel String?
A label that is used in the toString output. Intended to aid with identifying animation controller instances in debug output.
final
duration Duration?
The length of time this animation should last.
getter/setter pair
hashCode int
The hash code for this object.
no setterinherited
isAnimating bool
Whether this animation is currently animating in either the forward or reverse direction.
no setteroverride
isCompleted bool
Whether this animation is stopped at the end.
no setterinherited
isDismissed bool
Whether this animation is stopped at the beginning.
no setterinherited
isForwardOrCompleted bool
Whether the current aim of the animation is toward completion.
no setterinherited
lastElapsedDuration Duration?
The amount of time that has passed between the time the animation started and the most recent tick of the animation.
no setter
lowerBound double
The value at which this animation is deemed to be dismissed.
final
reverseDuration Duration?
The length of time this animation should last when going in reverse.
getter/setter pair
runtimeType Type
A representation of the runtime type of the object.
no setterinherited
status AnimationStatus
The current status of this animation.
no setteroverride
upperBound double
The value at which this animation is deemed to be completed.
final
value double
The current value of the animation.
getter/setter pairoverride-getter
velocity double
The rate of change of value per second.
no setter
view Animation<double>
Returns an Animation<double> for this animation controller, so that a pointer to this object can be passed around without allowing users of that pointer to mutate the AnimationController state.
no setter

Methods

addListener(VoidCallback listener) → void
Calls the listener every time the value of the animation changes.
inherited
addStatusListener(AnimationStatusListener listener) → void
Calls listener every time the status of the animation changes.
inherited
animateBack(double target, {Duration? duration, Curve curve = Curves.linear}) TickerFuture
Drives the animation from its current value to the given target, "backward".
animateTo(double target, {Duration? duration, Curve curve = Curves.linear}) TickerFuture
Drives the animation from its current value to the given target, "forward".
animateWith(Simulation simulation) TickerFuture
Drives the animation according to the given simulation.
clearListeners() → void
Removes all listeners added with addListener.
inherited
clearStatusListeners() → void
Removes all listeners added with addStatusListener.
inherited
didRegisterListener() → void
This implementation ignores listener registrations.
inherited
didUnregisterListener() → void
This implementation ignores listener registrations.
inherited
dispose() → void
Release the resources used by this object. The object is no longer usable after this method is called.
override
drive<U>(Animatable<U> child) Animation<U>
Chains a Tween (or CurveTween) to this Animation.
inherited
fling({double velocity = 1.0, SpringDescription? springDescription, AnimationBehavior? animationBehavior}) TickerFuture
Drives the animation with a spring (within lowerBound and upperBound) and initial velocity.
forward({double? from}) TickerFuture
Starts running this animation forwards (towards the end).
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
notifyListeners() → void
Calls all the listeners.
inherited
notifyStatusListeners(AnimationStatus status) → void
Calls all the status listeners.
inherited
removeListener(VoidCallback listener) → void
Stop calling the listener every time the value of the animation changes.
inherited
removeStatusListener(AnimationStatusListener listener) → void
Stops calling the listener every time the status of the animation changes.
inherited
repeat({double? min, double? max, bool reverse = false, Duration? period, int? count}) TickerFuture
Starts running this animation in the forward direction, and restarts the animation when it completes.
reset() → void
Sets the controller's value to lowerBound, stopping the animation (if in progress), and resetting to its beginning point, or dismissed state.
resync(TickerProvider vsync) → void
Recreates the Ticker with the new TickerProvider.
reverse({double? from}) TickerFuture
Starts running this animation in reverse (towards the beginning).
stop({bool canceled = true}) → void
Stops running this animation.
toggle({double? from}) TickerFuture
Toggles the direction of this animation, based on whether it isForwardOrCompleted.
toString() String
A string representation of this object.
inherited
toStringDetails() String
Provides a string describing the status of this object, but not including information about the object itself.
override

Operators

operator ==(Object other) bool
The equality operator.
inherited