didChangeMetrics method
Called when the application's dimensions change. For example, when a phone is rotated.
This method exposes notifications from dart:ui.PlatformDispatcher.onMetricsChanged.
{@tool snippet}
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();
WidgetsBinding.instance.addObserver(this);
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
// [View.of] exposes the view from `WidgetsBinding.instance.platformDispatcher.views`
// into which this widget is drawn.
_lastSize = View.of(context).physicalSize;
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
@override
void didChangeMetrics() {
setState(() { _lastSize = View.of(context).physicalSize; });
}
@override
Widget build(BuildContext context) {
return Text('Current size: $_lastSize');
}
}
{@end-tool}
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.sizeOf, which provides a similar service with less boilerplate.
Implementation
@override
void didChangeMetrics() {
if (PlatformCheck.isAndroid) {
final value = WidgetsBinding.instance!.window.viewInsets.bottom;
bool keyboardIsOpen = value > 0;
if (PlatformCheck.isAndroid && !keyboardIsOpen) {
keyboardIsOpen = _currentAction?.focusNode.hasFocus == true;
}
if (keyboardIsOpen) {
_onKeyboardChanged(true);
isKeyboardOpen = true;
} else {
_onKeyboardChanged(false);
isKeyboardOpen = false;
}
}
// Need to wait a frame to get the new size
WidgetsBinding.instance!.addPostFrameCallback((_) {
_updateOffset();
});
}