Answer
Overview
stands for Vertical Sync. In Flutter, it prevents an textvsync
text
AnimationControllerWhat vsync Does
Without vsync, an animation would update its values every frame even if the widget isn't on screen — wasting CPU and battery.
With vsync, the animation is synced to the screen's refresh rate and pauses automatically when the widget is not visible.
How to Use vsync
You provide
text
vsynctext
SingleTickerProviderStateMixintext
TickerProviderStateMixindartclass _MyWidgetState extends State<MyWidget> with SingleTickerProviderStateMixin { late AnimationController _controller; void initState() { super.initState(); _controller = AnimationController( vsync: this, // 'this' is the TickerProvider (vsync) duration: Duration(seconds: 2), ); } void dispose() { _controller.dispose(); // Always dispose! super.dispose(); } }
When to Use Which Mixin
| Mixin | Number of AnimationControllers |
|---|---|
text | Exactly one |
text | Multiple |
dart// One animation class _MyState extends State<MyWidget> with SingleTickerProviderStateMixin { late AnimationController _controller; } // Multiple animations class _MyState extends State<MyWidget> with TickerProviderStateMixin { late AnimationController _controller1; late AnimationController _controller2; }
What Happens Without vsync
dart// ❌ Without vsync — bad, but won't crash AnimationController( duration: Duration(seconds: 1), // No vsync — animation keeps firing even off-screen )
Flutter will show a warning:
textAnimationController objects should be disposed when no longer used.
vsync Lifecycle
textApp screen visible → Ticker running → AnimationController updates App goes background → Ticker paused → AnimationController paused App returns foreground → Ticker resumes → AnimationController resumes
Full Animation Example with vsync
dartclass PulsingIcon extends StatefulWidget { _PulsingIconState createState() => _PulsingIconState(); } class _PulsingIconState extends State<PulsingIcon> with SingleTickerProviderStateMixin { late AnimationController _controller; late Animation<double> _animation; void initState() { super.initState(); _controller = AnimationController( vsync: this, duration: Duration(milliseconds: 800), )..repeat(reverse: true); _animation = Tween<double>(begin: 0.8, end: 1.2).animate( CurvedAnimation(parent: _controller, curve: Curves.easeInOut), ); } void dispose() { _controller.dispose(); super.dispose(); } Widget build(BuildContext context) { return ScaleTransition( scale: _animation, child: Icon(Icons.favorite, size: 48, color: Colors.red), ); } }
Summary:
connects yourtextvsyncto the screen's frame timing, ensuring animations are efficient and pause when the widget is off-screen. Always usetextAnimationControllerfor one animation andtextSingleTickerProviderStateMixinfor multiple.textTickerProviderStateMixin