didChangeMetrics method Null safety
override
Called when the application's dimensions change. For example, when a phone is rotated.
This method exposes notifications from dart:ui.PlatformDispatcher.onMetricsChanged.
This StatefulWidget implements the parts of the State and
WidgetsBindingObserver protocols necessary to react when the device is
rotated (or otherwise changes dimensions).
class MetricsReactor extends StatefulWidget {
const MetricsReactor({ super.key });
@override
State<MetricsReactor> createState() => _MetricsReactorState();
}
class _MetricsReactorState extends State<MetricsReactor> with WidgetsBindingObserver {
late Size _lastSize;
@override
void initState() {
super.initState();
_lastSize = WidgetsBinding.instance.window.physicalSize;
WidgetsBinding.instance.addObserver(this);
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
@override
void didChangeMetrics() {
setState(() { _lastSize = WidgetsBinding.instance.window.physicalSize; });
}
@override
Widget build(BuildContext context) {
return Text('Current size: $_lastSize');
}
}
In general, this is unnecessary as the layout system takes care of automatically recomputing the application geometry when the application size changes.
See also:
- MediaQuery.of, which provides a similar service with less boilerplate.
Implementation
@override
void didChangeMetrics() {
if (_lastBottomViewInset != WidgetsBinding.instance.window.viewInsets.bottom) {
SchedulerBinding.instance.addPostFrameCallback((Duration _) {
_selectionOverlay?.updateForScroll();
});
if (_lastBottomViewInset < WidgetsBinding.instance.window.viewInsets.bottom) {
// Because the metrics change signal from engine will come here every frame
// (on both iOS and Android). So we don't need to show caret with animation.
_scheduleShowCaretOnScreen(withAnimation: false);
}
}
_lastBottomViewInset = WidgetsBinding.instance.window.viewInsets.bottom;
}