| name | lightweight-flutter-animations |
| description | Learn how to create a streamlined animation widget in Flutter that eliminates the need for `setState` by leveraging an abstract class and `SingleTickerProviderStateMixin` for efficient UI updates. |
| metadata | {"url":"https://rodydavis.com/posts/snippets/lightweight-flutter-animations","last_modified":"Tue, 03 Feb 2026 20:04:28 GMT"} |
Lightweight Flutter Animations
Overview
First we need to create the abstract class:
abstract class AnimationWidget<T extends StatefulWidget> extends State<T>
with SingleTickerProviderStateMixin {
Duration elapsed = Duration.zero;
Duration delta = Duration.zero;
late final Ticker ticker;
BoxConstraints constraints = const BoxConstraints.tightFor();
@override
void initState() {
super.initState();
ticker = createTicker((elapsed) {
delta = elapsed - this.elapsed;
this.elapsed = elapsed;
update(elapsed);
if (mounted) setState(() {});
});
ticker.start();
WidgetsBinding.instance.addPostFrameCallback(start);
}
@override
void dispose() {
ticker.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return LayoutBuilder(builder: (context, dimens) {
constraints = dimens;
return paint(context, dimens);
});
}
void start(Duration time) {}
void update(Duration time);
Widget paint(BuildContext context, BoxConstraints constraints);
}
This will let us replace State with AnimationWidget and not need to call setState to rebuild the ui.
Example
For the example we need an inline canvas painter:
class InlinePainter extends CustomPainter {
InlinePainter({
required this.draw,
super.repaint,
});
final void Function(Canvas canvas, Size size) draw;
@override
void paint(Canvas canvas, Size size) {
draw(canvas, size);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) => true;
}