聆听Flutter中设备方向的变化

时间:2019-03-04 15:49:05

标签: flutter

我正在寻找一种监听手机方向变化的方法,目的是在手机为横向手机时隐藏某些东西。

“我的布局”目前仅按预期方式以纵向显示,但是如果设备旋转到“横向”时我希望我的应用执行某些操作,同时将布局保持为“纵向”。

我尝试使用OrientationBuilder,但这仅在布局更改为“横向”时有效。

我也尝试过使用MediaQuery.of(context).orientation,但是一旦旋转设备,它将继续返回纵向,同样仅使用布局方向。

5 个答案:

答案 0 :(得分:1)

您可以听取屏幕尺寸的变化,但是MediaQuery.of(...)应该也可以正常工作,并且在方向改变时会重新构建窗口小部件

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');
  }
}

答案 1 :(得分:1)

在 didChangeMetrics() 中直接使用 MediaQuery 会返回以前的值。获取方向更改后的最新值。在其中使用 WidgetsBinding.instance.addPostFrameCallback()。 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'),
      ),
    );
  }
}

答案 2 :(得分:0)

您可以使用可见性包装小部件,并将opacity参数设置为getOpacityForOrientation(),然后在屏幕中可以添加以下功能:

double getOpacityForOrientation() {
    if (MediaQuery.of(context).orientation == Orientation.landscape) {
      return 0;
    } else {
      return 1;
    }
}

当方向更改时,小部件将重建,并且不透明度也会更改并隐藏/显示

答案 3 :(得分:0)

OrientationBuilderMediaQuery.of(context).orientation都应该能够完成工作。但是您是说设备的方向永远不会改变,这使我认为您尚未在设备中启用自动旋转。

您可以从快速设置中启用自动旋转并尝试一下吗?

答案 4 :(得分:-1)

只要使用这样的代码,如果你想检测设备的方向

String type_orien = "potrait";

Future<void> detect_change_orientation() async {
  await Future.delayed(const Duration(seconds: 1), () async {
  if (MediaQuery.of(context).orientation == Orientation.landscape) {
    if (type_orien ==
        "potrait") // if orien change and before is potrait then reload again
    {
      print("landscape ss");
      await reload_set_scren();
      type_orien = "landscape";
    }
  } else {
    if (type_orien ==
        "landscape") // if orien change and before is landscape then reload again
    {
      print("potrait ss");
      await reload_set_scren();
      type_orien = "potrait";
     }
    }
  });
}

Future<void> reload_set_scren() {
//... do whats ever u want
}

@override
Widget build(BuildContext context) {



  detect_change_orientation(); // call function here <--


return Scaffold(
    );
}

#timikapapuaindonesia