'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