When using AnimationController, what is the purpose of that vsync
parameter?
class Example extends StatefulWidget {
@override
_ExampleState createState() => _ExampleState();
}
class _ExampleState extends State<Example> with SingleTickerProviderStateMixin {
AnimationController controller;
@override
void initState() {
super.initState();
controller = AnimationController(
duration: const Duration(seconds: 2),
vsync: this, // Why do we need this?
);
}
// ...
}
What is vsync ? Vsync basically keeps the track of screen, so that Flutter does not renders the animation when the screen is not being displayed.
Timer is unrelated to Flutter, and is just a timer like you'd fine in any other language. On the other hand, AnimationController (and Ticker , its equivalent of Timer ) is Flutter specific. The difference with a Timer is that, by using AnimationController , the "ticker" can be muted, slowed, or mocked.
Provides Ticker objects that are configured to only tick while the current tree is enabled, as defined by TickerMode. To create an AnimationController in a class that uses this mixin, pass vsync: this to the animation controller constructor whenever you create a new animation controller.
Internally, Flutter uses a scheduler that renders the screen at 60 frames per second.
AnimationController's vsync
parameter has one purpose: Controlling the progress of the animation based on external factors.
There are typically three main usages:
vsync
, this allows tests to skip frames to target a very specific state of the animation. This is both precise and doesn't involve waiting for real-time.The last scenario is the main reason why our widgets need to that SingleTickerProviderStateMixin. Knowing what widget is associated with the animation matters. We can't just use a TickerProvider obtained from the root widget of our application.
Through that vsync
, this will avoid scenarios where our widget is no longer visible (for example if another route is pushed on the top of it), but the animation is still playing and therefore makes our screen to keep refreshing
A way of seeing that behavior is by using the "performance overlay" devtool combined with widgets like CircularProgressIndicator, which internally uses AnimationController.
If we use Opacity
to hide our indicator (which doesn't pause animations):
Opacity(
opacity: 0,
child: CircularProgressIndicator(),
)
Then the performance overlay shows that our screen keeps refreshing:
Now, if we add a TickerMode (implicitly done by widgets like Visibility and Navigator), we can pause the animation, which stops the unnecessary refresh:
Opacity(
opacity: 0,
child: TickerMode(
enabled: false,
child: CircularProgressIndicator(),
),
),
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With