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

后端 未结 6 1413
南方客
南方客 2020-11-28 22:45

On one of my flutter pages, I need the screen to set to landscape mode and lock it so it can\'t rotate into portrait mode, but only on the one page. So need a way to enable

6条回答
  •  囚心锁ツ
    2020-11-28 23:13

    I would use a simple mixin to lock phone in portrait. The following solution locks the entire app in portrait or sets specific screens to portrait while keeping rotation elsewere.

    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 on State {
      @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,
      ]);
    }
    

    To block rotation in the entire app implement PortraitModeMixin in the main App widget. Remember to call super.build(context) in Widget build(BuildContext context) method.

    /// 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"),
        );
      }
    }
    

    To block rotation in a specific screen implement PortraitStatefulModeMixin in the specific screen's state. Remember to call super.build(context) in the State's build() method and super.dispose() in dispose() method. If your screen is a StatelessWidget - simply repeat the App's solution (previous example) i.e. use PortraitModeMixin.

    /// Specific screen
    class SampleScreen extends StatefulWidget {
      SampleScreen() : super();
    
      @override
      State createState() => _SampleScreenState();
    }
    
    class _SampleScreenState extends State
        with PortraitStatefulModeMixin {
      @override
      Widget build(BuildContext context) {
        super.build(context);
        return Text("Flutter - Block screen rotation example");
      }
    
      @override
      void dispose() {
         super.dispose();
      }
    }
    

    Mixins with such syntax work from Dart 2.1

提交回复
热议问题