Add example for locking screen orientation in a letterboxing environment (#131266)
Android may choose to letterbox applications that lock orientation. This gets particularly bad on foldable devices, where a developer may want to lock orientation when the devices is folded and unlock when unfolded. However, if the app is letterboxed when unfolded, the `MediaQuery.of(context).size` will never report the full display size, only the letterboxed window size. This may result in an application getting "stuck" in portrait mode. /cc @TytaniumDev
This commit is contained in:
parent
eb4891226e
commit
efa69ba95b
@ -368,6 +368,74 @@ abstract final class SystemChrome {
|
||||
///
|
||||
/// ## Limitations
|
||||
///
|
||||
/// ### Android
|
||||
///
|
||||
/// Android screens may choose to [letterbox](https://developer.android.com/guide/practices/enhanced-letterboxing)
|
||||
/// applications that lock orientation, particularly on larger screens. When
|
||||
/// letterboxing occurs on Android, the [MediaQueryData.size] reports the
|
||||
/// letterboxed size, not the full screen size. Applications that make
|
||||
/// decisions about whether to lock orientation based on the screen size
|
||||
/// must use the `display` property of the current [FlutterView].
|
||||
///
|
||||
/// ```dart
|
||||
/// // A widget that locks the screen to portrait if it is less than 600
|
||||
/// // logical pixels wide.
|
||||
/// class MyApp extends StatefulWidget {
|
||||
/// const MyApp({ super.key });
|
||||
///
|
||||
/// @override
|
||||
/// State<MyApp> createState() => _MyAppState();
|
||||
/// }
|
||||
///
|
||||
/// class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
|
||||
/// ui.Display? _display;
|
||||
/// static const double kOrientationLockBreakpoint = 600;
|
||||
///
|
||||
/// @override
|
||||
/// void initState() {
|
||||
/// super.initState();
|
||||
/// WidgetsBinding.instance.addObserver(this);
|
||||
/// }
|
||||
///
|
||||
/// @override
|
||||
/// void didChangeDependencies() {
|
||||
/// super.didChangeDependencies();
|
||||
/// _display = View.maybeOf(context)?.display;
|
||||
/// }
|
||||
///
|
||||
/// @override
|
||||
/// void dispose() {
|
||||
/// WidgetsBinding.instance.removeObserver(this);
|
||||
/// _display = null;
|
||||
/// super.dispose();
|
||||
/// }
|
||||
///
|
||||
/// @override
|
||||
/// void didChangeMetrics() {
|
||||
/// final ui.Display? display = _display;
|
||||
/// if (display == null) {
|
||||
/// return;
|
||||
/// }
|
||||
/// if (display.size.width / display.devicePixelRatio < kOrientationLockBreakpoint) {
|
||||
/// SystemChrome.setPreferredOrientations(<DeviceOrientation>[
|
||||
/// DeviceOrientation.portraitUp,
|
||||
/// ]);
|
||||
/// } else {
|
||||
/// SystemChrome.setPreferredOrientations(<DeviceOrientation>[]);
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// @override
|
||||
/// Widget build(BuildContext context) {
|
||||
/// return const MaterialApp(
|
||||
/// home: Placeholder(),
|
||||
/// );
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// ### iOS
|
||||
///
|
||||
/// This setting will only be respected on iPad if multitasking is disabled.
|
||||
///
|
||||
/// You can decide to opt out of multitasking on iPad, then
|
||||
|
@ -139,10 +139,15 @@ abstract mixin class WidgetsBindingObserver {
|
||||
/// @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;
|
||||
/// WidgetsBinding.instance.addObserver(this);
|
||||
/// }
|
||||
///
|
||||
/// @override
|
||||
|
Loading…
x
Reference in New Issue
Block a user