after_first_frame_mixin
Run code after the first layout of a widget has been performed, i.e. after the first frame has been displayed.
initState runs before layout, so the context it sees has no size, no route
transition in place and no Scaffold to show a snack bar in. This package gives
you a callback that runs once the frame is on screen, as a mixin or as a
widget.
Installation
dependencies:
after_first_frame_mixin: ^1.0.0
Requires Dart 3.8 / Flutter 3.32 or newer.
Usage
As a mixin
class HomeScreenState extends State<HomeScreen>
with AfterFirstFrameMixin<HomeScreen> {
@override
Widget build(BuildContext context) => const Center(child: Text('Example'));
@override
FutureOr<void> afterFirstFrame(BuildContext context) {
showDialog<void>(
context: context,
builder: (BuildContext context) =>
const AlertDialog(content: Text('Hello World')),
);
}
}
As a widget
For a subtree that would otherwise have no reason to be stateful:
AfterFirstFrame(
onFirstFrame: (BuildContext context) => ScaffoldMessenger.of(context)
.showSnackBar(const SnackBar(content: Text('Ready'))),
child: const HomeBody(),
)
Later frames
afterNextFrame is the counterpart for everything after the first frame — for
instance to measure a layout that a setState has just changed. It can be
called at any point in the widget's life and schedules a frame if none is
pending.
void _grow() {
setState(() => _width += 40);
afterNextFrame((_) {
final RenderBox box = _key.currentContext!.findRenderObject()! as RenderBox;
setState(() => _measured = box.size);
});
}
hasRenderedFirstFrame tells you which side of the first frame you are on:
if (hasRenderedFirstFrame) {
// safe to touch layout-dependent things
}
API
| Member | Description |
|---|---|
AfterFirstFrameMixin<T> |
Mixin on State<T>. Implement afterFirstFrame. |
afterFirstFrame(BuildContext) |
Called once, after the first frame. May return a Future. |
afterNextFrame(callback) |
Runs callback after the next frame. Callable at any time. |
hasRenderedFirstFrame |
Whether the first frame has been displayed. |
AfterFirstFrame |
Widget form: onFirstFrame + child. |
AfterFrameCallback |
FutureOr<void> Function(BuildContext context). |
Notes
- Callbacks never run after the
Statehas been unmounted. - Errors — including those thrown by an asynchronous callback — are reported
through
FlutterError.reportError, so they reachFlutterError.onErrorandtester.takeException()instead of escaping as unhandled async errors. - Scheduling relies on
WidgetsBinding.instance.endOfFrame. If the device screen is off, frames are not produced and the callback waits.
Example
A runnable app demonstrating all three APIs is in the /example folder.
Libraries
- after_first_frame_mixin
- Run code after the first frame of a widget has been displayed.