'Listening For Device Orientation Changes In Flutter
I am looking for a way of listening for changes to the phones orientation, with the intent to hide something if the phone is Landscape.
My Layout is currently only displayed in portrait, as intended, but I want my app to do something if the device is rotated to Landscape, while keeping the layout in Portrait.
I have tried using a OrientationBuilder
, but this only works if the layout changes to Landscape.
I have also tried using MediaQuery.of(context).orientation
, but it continues to return portrait once the device is rotated, again only using the layouts orientation.
Solution 1:[1]
You can listen to screen size changes, but MediaQuery.of(...)
should work as well and should cause rebuilds of your widget when orientation changes
https://stephenmann.io/post/listening-to-device-rotations-in-flutter/
import 'dart:ui'; import 'package:flutter/material.dart'; class WidthHeight extends StatefulWidget { WidthHeight({ Key key }) : super(key: key); @override WidthHeightState createState() => new WidthHeightState(); } class WidthHeightState extends State with WidgetsBindingObserver { @override void initState() { super.initState(); WidgetsBinding.instance.addObserver(this); } @override void dispose() { WidgetsBinding.instance.removeObserver(this); super.dispose(); } double width = 0.0; double height = 0.0; @override void didChangeMetrics() { setState(() { width = window.physicalSize.width; height = window.physicalSize.height; }); } @override Widget build(BuildContext context) { return new Text('Width: $width, Height $height'); } }
Solution 2:[2]
You can wrap your widget with visibility and set the opacity parameter to getOpacityForOrientation() and in your Screen you can add the function:
double getOpacityForOrientation() {
if (MediaQuery.of(context).orientation == Orientation.landscape) {
return 0;
} else {
return 1;
}
}
when the orientation changes the widget will rebuild and the opacity will change and hide/show
Solution 3:[3]
Using MediaQuery directly in didChangeMetrics() returns previous values. To get the latest values after orientation change. Use WidgetsBinding.instance.addPostFrameCallback() inside it. https://github.com/flutter/flutter/issues/60899
class OrientationSample extends StatefulWidget {
const OrientationSample({Key? key}) : super(key: key);
@override
_OrientationSampleState createState() => _OrientationSampleState();
}
class _OrientationSampleState extends State<OrientationSample> with WidgetsBindingObserver {
Orientation? _currentOrientation;
@override
void initState() {
super.initState();
WidgetsBinding.instance?.addObserver(this);
}
@override
void dispose() {
WidgetsBinding.instance?.removeObserver(this);
super.dispose();
}
@override
void didChangeMetrics() {
_currentOrientation = MediaQuery.of(context).orientation;
print('Before Orientation Change: $_currentOrientation');
WidgetsBinding.instance?.addPostFrameCallback((timeStamp) {
setState(() {
_currentOrientation = MediaQuery.of(context).orientation;
});
print('After Orientation Change: $_currentOrientation');
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: _currentOrientation != null ? Text('$_currentOrientation') : Text('Rotate Device to Test'),
),
);
}
}
Solution 4:[4]
Both OrientationBuilder
and MediaQuery.of(context).orientation
should be able to get the job done. But you're saying that the device's orientation never changes which makes me think that you have not enabled auto-rotate in your device.
Can you enable auto-rotate from quick settings and give it a try?
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Günter Zöchbauer |
Solution 2 | Hussein Abdallah |
Solution 3 | |
Solution 4 |