ListenableBuilder Patterns in Flutter: Reactive UI Without Streams
Rebuild parts of your UI from any Listenable with ListenableBuilder — animations, controllers, and notifiers without StreamBuilders.
Published on • November 4, 2026
AI Assistant

ListenableBuilder is the general-purpose rebuild widget: give it any Listenable — a ChangeNotifier, an Animation, a TextEditingController, a scroll controller — and its builder reruns whenever it fires. It replaced the old AnimatedBuilder-only mindset for non-animation use cases.
The basic shape
ListenableBuilder(
listenable: myNotifier,
builder: (context, _) {
return Text('${myNotifier.value}');
},
)
The second builder argument is the child widget (for optimization); most of the time you ignore it with _.
Rebuilding from a controller
ListenableBuilder(
listenable: textController,
builder: (context, _) {
final length = textController.text.length;
return Text('$length / 280');
},
)
This is a cleaner alternative to attaching a listener manually and calling setState — no initState/dispose bookkeeping.
Multiple listenables
ListenableBuilder accepts a listenable that can be a Listenable — but for several sources, compose them:
ListenableBuilder(
listenable: Listenable.merge([notifierA, notifierB]),
builder: (context, _) => Text('${notifierA.value} + ${notifierB.value}'),
)
Listenable.merge creates a fan-in that fires when any source fires.
Rebuilding only part of the tree
Place ListenableBuilder as low in the tree as possible. Rebuilding a whole page from a text controller wastes work; wrap just the character counter instead. This is the “islands” mindset applied to state: the narrower the listener scope, the fewer rebuilds.
Takeaway: ListenableBuilder rebuilds from any Listenable — controllers, notifiers, animations — replacing manual listener/setState boilerplate. Scope it low in the tree, and use Listenable.merge to fan in multiple sources.