Flutter:如何按需设置和锁定屏幕方向


82

在我的第一页上,我需要将屏幕设置为横向模式并锁定它,以使其不能旋转到纵向模式,而只能在一页上旋转。因此需要一种即时启用此功能的方法。有人知道怎么做吗?

我希望它可以向左旋转风景或向右旋转风景,只是不进入纵向模式。

Answers:


168

首先导入服务包:

import 'package:flutter/services.dart';

这将使您可以访问该SystemChrome课程,"Controls specific aspects of the operating system's graphical interface and how it interacts with the application."

加载小部件时,请执行以下操作:

@override
void initState(){
  super.initState();
  SystemChrome.setPreferredOrientations([
      DeviceOrientation.landscapeRight,
      DeviceOrientation.landscapeLeft,
  ]);
}

然后当我离开页面时,将其恢复为正常状态,如下所示:

@override
dispose(){
  SystemChrome.setPreferredOrientations([
    DeviceOrientation.landscapeRight,
    DeviceOrientation.landscapeLeft,
    DeviceOrientation.portraitUp,
    DeviceOrientation.portraitDown,
  ]);
  super.dispose();
}

2
但似乎只能在android上运行github.com/flutter/flutter/issues/20124
Luigino De Togni

哦,我没意识到。这很有可能,我只在Android上进行了测试。
Jus10

没关系,可以通过Platform Channel github.com/flutter/flutter/issues/13238#issuecomment-435958221来解决,我认为它将很快得到解决
Luigino De Togni

20
只是为了指定此错误已在几个月前解决,并且此解决方案现在也适用于iOS
Pablo Insua,

1
从我看来,在dispose方法中设置首选方向并不是一个好主意。如果导航到另一条路线并且打算返回,则不会调用dispose方法。
罗恩·贡捷

27

我将使用一个简单的mixin手机锁定为纵向模式。以下解决方案将整个应用程序锁定为纵向模式,将特定屏幕设置为纵向模式,同时保持旋转状态。

import 'package:flutter/cupertino.dart';
import 'package:flutter/services.dart';

/// Forces portrait-only mode application-wide
/// Use this Mixin on the main app widget i.e. app.dart
/// Flutter's 'App' has to extend Stateless widget.
///
/// Call `super.build(context)` in the main build() method
/// to enable portrait only mode
mixin PortraitModeMixin on StatelessWidget {
  @override
  Widget build(BuildContext context) {
    _portraitModeOnly();
    return null;
  }
}

/// Forces portrait-only mode on a specific screen
/// Use this Mixin in the specific screen you want to
/// block to portrait only mode.
///
/// Call `super.build(context)` in the State's build() method
/// and `super.dispose();` in the State's dispose() method
mixin PortraitStatefulModeMixin<T extends StatefulWidget> on State<T> {
  @override
  Widget build(BuildContext context) {
    _portraitModeOnly();
    return null;
  }

  @override
  void dispose() {
    _enableRotation();
  }
}

/// blocks rotation; sets orientation to: portrait
void _portraitModeOnly() {
  SystemChrome.setPreferredOrientations([
    DeviceOrientation.portraitUp,
    DeviceOrientation.portraitDown,
  ]);
}

void _enableRotation() {
  SystemChrome.setPreferredOrientations([
    DeviceOrientation.portraitUp,
    DeviceOrientation.portraitDown,
    DeviceOrientation.landscapeLeft,
    DeviceOrientation.landscapeRight,
  ]);
}

阻止整个应用PortraitModeMixin中的旋转,请在主App窗口小部件中实施。记得打电话super.build(context)Widget build(BuildContext context)方法。

/// Main App widget
class App extends StatelessWidget with PortraitModeMixin {
  const App();

  @override
  Widget build(BuildContext context) {
    super.build(context);
    return CupertinoApp(
      title: 'Flutter Demo',
      theme: CupertinoThemeData(),
      home: Text("Block screen rotation example"),
    );
  }
}

为了阻止旋转在一个特定的屏幕落实PortraitStatefulModeMixin<SampleScreen>在具体的屏幕的状态。记住要调用super.build(context)State的build()方法和super.dispose()indispose()方法。如果您的屏幕是StatelessWidget-只需重复应用程序的解决方案(上一个示例),即使用PortraitModeMixin

/// Specific screen
class SampleScreen extends StatefulWidget {
  SampleScreen() : super();

  @override
  State<StatefulWidget> createState() => _SampleScreenState();
}

class _SampleScreenState extends State<SampleScreen>
    with PortraitStatefulModeMixin<SampleScreen> {
  @override
  Widget build(BuildContext context) {
    super.build(context);
    return Text("Flutter - Block screen rotation example");
  }

  @override
  void dispose() {
     super.dispose();
  }
}

具有此类语法的Mixins从Dart 2.1开始工作


1
我已经试过了您的mixin类-无状态版本可以正常工作,但是一旦我的statefull类调用其处置方法,则statefull会引发异常。注意,我super.dispose()在课堂上打电话。下面是错误:I / flutter(29686):在结束小部件树时引发了以下断言:I / flutter(29686):_MultiPlayerAcceptPageState.dispose未能调用super.dispose。I / flutter(29686):dispose()实现必须始终调用其超类dispose()方法,以确保小部件使用的所有I / flutter(29686):资源都已完全释放。
Angel Todorov

有状态版本也是如此。您解决了这个问题吗?
窃窃私语

5
void main() {
  WidgetsFlutterBinding.ensureInitialized();
  SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp, DeviceOrientation.portraitDown])
    .then((_) {
      runApp(new MyApp());
    });
}

3
尽管此代码可以为问题提供解决方案,但最好添加有关其原因/工作方式的上下文。这可以帮助将来的用户学习并将该知识应用于他们自己的代码。在解释代码时,您还可能以投票的形式从用户那里获得积极的反馈。
borchvm'5

5

有时由于有关方向的空信息而无法使用。您可以像这样简单地使用它:

import services.dart


void main() {
    SystemChrome.setPreferredOrientations(
    [DeviceOrientation.portraitUp]
     )
        .then((_) {
          runApp(new MyApp());
        });
    }

//启动应用程序后等待设置屏幕方向,然后->然后锁定方向


2

导入services.dart,您的void main功能应类似于:

void main(){

    WidgetsFlutterBinding.ensureInitialized();
    SystemChrome.setPreferredOrientations(
       [DeviceOrientation.portraitUp, DeviceOrientation.portraitDown])
       .then((_){
           runApp(MyApp());
       }
    );
}


0

导入services.dart包并添加以下代码以将设备方向锁定为portraitUp模式:

 import 'package:flutter/services.dart';

 main() {
     WidgetsFlutterBinding.ensureInitialized();
     SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
     runApp(MyHomePage());
 }
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.