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

Flutter: How to set and lock screen orientation on-demand

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

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


首先导入服务包:

import 'package:flutter/services.dart';

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

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

1
2
3
4
5
6
7
8
@override
void initState(){
  super.initState();
  SystemChrome.setPreferredOrientations([
      DeviceOrientation.landscapeRight,
      DeviceOrientation.landscapeLeft,
  ]);
}

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

1
2
3
4
5
6
7
8
9
10
@override
dispose(){
  SystemChrome.setPreferredOrientations([
    DeviceOrientation.landscapeRight,
    DeviceOrientation.landscapeLeft,
    DeviceOrientation.portraitUp,
    DeviceOrientation.portraitDown,
  ]);
  super.dispose();
}


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
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,
  ]);
}

要阻止整个应用程序中的旋转,请在主App小部件中实现PortraitModeMixin。请记住在Widget build(BuildContext context)方法中调用super.build(context)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/// 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。请记住在State的build()方法中调用super.build(context),在dispose()方法中调用super.dispose()。如果您的屏幕是StatelessWidget-只需重复应用程序的解决方案(前面的示例),即使用PortraitModeMixin

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/// 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开始工作


有时由于有关方向的空信息而无法使用。
您可以这样使用smth:

1
2
3
4
5
6
7
8
9
10
    void main() {
    SystemChrome.setPreferredOrientations(
    [DeviceOrientation.portraitUp]
     )
        .then((_) {
          runApp(new MyApp());
        });
    }
// wait for settings screen orientation after
initating app and then lock orientation

导入services.dart,您的void main函数应类似于:

1
2
3
4
5
6
7
8
9
10
void main(){

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


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