在 Flutter 中监听设备方向的变化

Mat*_*ing 16 flutter

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

我的布局目前仅按预期以纵向显示,但我希望我的应用程序在设备旋转为横向时执行某些操作,同时保持纵向布局。

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

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

Gün*_*uer 12

您可以收听屏幕尺寸的变化,但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');
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,但仅当布局从纵向切换为横向时才调用 didChangeMetrics(),反之亦然,我希望我的布局保持纵向,并且仅在设备移动到纵向时更改单个小部件 (2认同)
  • @MatthewWeilding 有更新吗?尝试做同样的事情,即在屏幕旋转后接收回调,即使设置了“SystemChrome.setPreferredOrientations([ DeviceOrientation.portraitUp ]);” (2认同)

har*_*anx 8

直接在 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'),
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)


Hus*_*lah 5

您可以用可见性包装您的小部件,并将不透明度参数设置为 getOpacityForOrientation(),然后在您的屏幕中您可以添加该函数:

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

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