Flutter:如何按需设置和锁定屏幕方向
Flutter: How to set and lock screen orientation on-demand
在我的一个 flutter 页面上,我需要将屏幕设置为横向模式并将其锁定,这样它就不能旋转到纵向模式,但只能在一页上。所以需要一种方法来即时启用此功能。有人知道怎么做吗?
我希望它向左横向或向右旋转,只是不要进入纵向模式。
首先导入服务包:
import 'package:flutter/services.dart';
这将使您能够访问 SystemChrome
class,其中 "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();
}
我会使用一个简单的mixin来锁定phone纵向。以下解决方案将整个应用程序锁定为纵向或将特定屏幕设置为纵向,同时保持其他屏幕旋转。
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)
。
/// 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>
。记得在State的build()
方法中调用super.build(context)
,在dispose()
方法中调用super.dispose()
。如果您的屏幕是 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();
}
}
来自 Dart 2.1 的具有这种语法的 Mixins
有时由于有关方向的信息为空,因此无法正常工作。
您可以像这样简单地使用它:
import services.dart
void main() {
SystemChrome.setPreferredOrientations(
[DeviceOrientation.portraitUp]
)
.then((_) {
runApp(new MyApp());
});
}
// 启动应用后等待设置屏幕方向 -> 然后锁定方向
void main() {
WidgetsFlutterBinding.ensureInitialized();
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp, DeviceOrientation.portraitDown])
.then((_) {
runApp(new MyApp());
});
}
import services.dart
你的 void main
函数应该是这样的:
void main(){
WidgetsFlutterBinding.ensureInitialized();
SystemChrome.setPreferredOrientations(
[DeviceOrientation.portraitUp, DeviceOrientation.portraitDown])
.then((_){
runApp(MyApp());
}
);
}
您可以为此 https://pub.dev/packages/orientation_helper 使用 orientation_helper。它的主要目标是为应用程序中的每个屏幕设置方向。
导入 services.dart 包并添加以下代码以将设备方向锁定为 portraitUp 模式:
import 'package:flutter/services.dart';
main() {
WidgetsFlutterBinding.ensureInitialized();
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
runApp(MyHomePage());
}
对iOS很重要。
- 在 info.plist 文件中启用方向。例如
步骤
- 在 main.dart 文件中设置方向。就我而言,我的应用程序仅支持单屏以外的纵向模式,因此我需要在第一次设置纵向模式。例如
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp,DeviceOrientation.portraitDown,]);
- 在需要旋转的屏幕中添加以下代码。
void initState() {
super.initState();
SystemChrome.setPreferredOrientations([
DeviceOrientation.landscapeRight,
DeviceOrientation.landscapeLeft,
]);
}
@override
dispose(){
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]);
super.dispose();
}
首先,将整个应用程序方向锁定为纵向模式。
//Do this in main.dart
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp])
.then((_) {
runApp(MyApp());
});
其次,转到要更改方向的特定屏幕。
@override
void initState() {
super.initState();
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.landscapeRight,
DeviceOrientation.landscapeLeft
]);
}
@override
void dispose() {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
_interstitialAd.dispose();
super.dispose();
}
要使用 SystemChrome,您必须添加 'package:flutter/services.dart'
在整个应用程序中锁定屏幕方向的简单方法
将 import 'package:flutter/services.dart';
添加到 main.dart
文件的开头。
创建 SystemChrome.setPreferredOrientations();
方法以在 MyApp
class 的 return
部分之前的 Widget 构建区域中禁用屏幕旋转。
在方法的参数中使用 [DeviceOrientation.<orientation-type>]
指定方向。
使用以下选项之一代替 <orientation-type>
:
portraitUp
portraitDown
landscapeLeft
landscapeRight
示例代码:
import 'package:flutter/material.dart';
import 'package:flutter/services.dart' ;
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
]);
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("Screen Orientation"),
),
body: Container(
),
),
);
}
}
对于那些喜欢使用钩子的人
import 'package:flutter/services.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
useOrientation(List<DeviceOrientation> orientations) {
useEffect(
() {
SystemChrome.setPreferredOrientations(orientations);
return () {
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
DeviceOrientation.landscapeLeft,
DeviceOrientation.landscapeRight,
]);
};
},
);
}
像这样使用它:
class MyWidget extends HookWidget {
void build(BuildContext context) {
useOrientation([DeviceOrientation.portraitUp]);
return Container();
}
}
设置flutter中的首选方向。
// import this package
import 'package:flutter/services.dart';
// Lock the orientation to Portrait Only
WidgetsFlutterBinding.ensureInitialized();
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp])
.then((value) => runApp(MyApp()));
您还可以在 setPreferredOrientations
列表中添加首选方向,例如 [DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]
以下是您可以设置的方向:
/// If the device shows its boot logo in portrait, then the boot logo is shown
/// in [portraitUp]. Otherwise, the device shows its boot logo in landscape
/// and this orientation is obtained by rotating the device 90 degrees
/// clockwise from its boot orientation.
portraitUp,
/// The orientation that is 90 degrees clockwise from [portraitUp].
///
/// If the device shows its boot logo in landscape, then the boot logo is
/// shown in [landscapeLeft].
landscapeLeft,
/// The orientation that is 180 degrees from [portraitUp].
portraitDown,
/// The orientation that is 90 degrees counterclockwise from [portraitUp].
landscapeRight,
参考:https://greymag.medium.com/flutter-orientation-lock-portrait-only-c98910ebd769
在 activity 标签下主文件夹中的 AndroidManifest 文件中设置 android:screenOrientation = "portrait"
<activity android:windowSoftInputMode="adjustResize" android:screenOrientation = "portrait">
在GetX中,你需要像这个例子一样使用GetBuilder:
final Controller ctrl = Get.find();
GetBuilder<Controller>(
initState: (_) => ctrl.setLandscape(),
dispose: (_) => ctrl.setPortrait(),
builder: (code) => Container(
padding: const EdgeInsets.zero,
alignment: Alignment.Center,
child: const SizedBox(),
),
),
In Controller file:
class Controller extends GetxController {
RxBool isLandscape = false.obs;
Future<void> setLandscape() async {
if (isLandscape.isTrue) {
await SystemChrome.setPreferredOrientations([DeviceOrientation.landscapeLeft]);
update();
}
}
Future<void> setPortrait() async {
if (isLandscape.isFalse) {
await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
update();
}
}
}
我希望这个解决方案能够回答使用 GetX 作为主要状态管理的开发人员。祝你好运,兄弟!上帝保佑你们。
在我的一个 flutter 页面上,我需要将屏幕设置为横向模式并将其锁定,这样它就不能旋转到纵向模式,但只能在一页上。所以需要一种方法来即时启用此功能。有人知道怎么做吗?
我希望它向左横向或向右旋转,只是不要进入纵向模式。
首先导入服务包:
import 'package:flutter/services.dart';
这将使您能够访问 SystemChrome
class,其中 "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();
}
我会使用一个简单的mixin来锁定phone纵向。以下解决方案将整个应用程序锁定为纵向或将特定屏幕设置为纵向,同时保持其他屏幕旋转。
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)
。
/// 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>
。记得在State的build()
方法中调用super.build(context)
,在dispose()
方法中调用super.dispose()
。如果您的屏幕是 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();
}
}
来自 Dart 2.1 的具有这种语法的 Mixins
有时由于有关方向的信息为空,因此无法正常工作。 您可以像这样简单地使用它:
import services.dart
void main() {
SystemChrome.setPreferredOrientations(
[DeviceOrientation.portraitUp]
)
.then((_) {
runApp(new MyApp());
});
}
// 启动应用后等待设置屏幕方向 -> 然后锁定方向
void main() {
WidgetsFlutterBinding.ensureInitialized();
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp, DeviceOrientation.portraitDown])
.then((_) {
runApp(new MyApp());
});
}
import services.dart
你的 void main
函数应该是这样的:
void main(){
WidgetsFlutterBinding.ensureInitialized();
SystemChrome.setPreferredOrientations(
[DeviceOrientation.portraitUp, DeviceOrientation.portraitDown])
.then((_){
runApp(MyApp());
}
);
}
您可以为此 https://pub.dev/packages/orientation_helper 使用 orientation_helper。它的主要目标是为应用程序中的每个屏幕设置方向。
导入 services.dart 包并添加以下代码以将设备方向锁定为 portraitUp 模式:
import 'package:flutter/services.dart';
main() {
WidgetsFlutterBinding.ensureInitialized();
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
runApp(MyHomePage());
}
对iOS很重要。
- 在 info.plist 文件中启用方向。例如
步骤
- 在 main.dart 文件中设置方向。就我而言,我的应用程序仅支持单屏以外的纵向模式,因此我需要在第一次设置纵向模式。例如
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp,DeviceOrientation.portraitDown,]);
- 在需要旋转的屏幕中添加以下代码。
void initState() {
super.initState();
SystemChrome.setPreferredOrientations([
DeviceOrientation.landscapeRight,
DeviceOrientation.landscapeLeft,
]);
}
@override
dispose(){
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]);
super.dispose();
}
首先,将整个应用程序方向锁定为纵向模式。
//Do this in main.dart
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp])
.then((_) {
runApp(MyApp());
});
其次,转到要更改方向的特定屏幕。
@override
void initState() {
super.initState();
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.landscapeRight,
DeviceOrientation.landscapeLeft
]);
}
@override
void dispose() {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
_interstitialAd.dispose();
super.dispose();
}
要使用 SystemChrome,您必须添加 'package:flutter/services.dart'
在整个应用程序中锁定屏幕方向的简单方法
将
import 'package:flutter/services.dart';
添加到main.dart
文件的开头。创建
SystemChrome.setPreferredOrientations();
方法以在MyApp
class 的return
部分之前的 Widget 构建区域中禁用屏幕旋转。在方法的参数中使用
[DeviceOrientation.<orientation-type>]
指定方向。
使用以下选项之一代替 <orientation-type>
:
portraitUp
portraitDown
landscapeLeft
landscapeRight
示例代码:
import 'package:flutter/material.dart';
import 'package:flutter/services.dart' ;
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
]);
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("Screen Orientation"),
),
body: Container(
),
),
);
}
}
对于那些喜欢使用钩子的人
import 'package:flutter/services.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
useOrientation(List<DeviceOrientation> orientations) {
useEffect(
() {
SystemChrome.setPreferredOrientations(orientations);
return () {
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
DeviceOrientation.landscapeLeft,
DeviceOrientation.landscapeRight,
]);
};
},
);
}
像这样使用它:
class MyWidget extends HookWidget {
void build(BuildContext context) {
useOrientation([DeviceOrientation.portraitUp]);
return Container();
}
}
设置flutter中的首选方向。
// import this package
import 'package:flutter/services.dart';
// Lock the orientation to Portrait Only
WidgetsFlutterBinding.ensureInitialized();
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp])
.then((value) => runApp(MyApp()));
您还可以在 setPreferredOrientations
列表中添加首选方向,例如 [DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]
以下是您可以设置的方向:
/// If the device shows its boot logo in portrait, then the boot logo is shown
/// in [portraitUp]. Otherwise, the device shows its boot logo in landscape
/// and this orientation is obtained by rotating the device 90 degrees
/// clockwise from its boot orientation.
portraitUp,
/// The orientation that is 90 degrees clockwise from [portraitUp].
///
/// If the device shows its boot logo in landscape, then the boot logo is
/// shown in [landscapeLeft].
landscapeLeft,
/// The orientation that is 180 degrees from [portraitUp].
portraitDown,
/// The orientation that is 90 degrees counterclockwise from [portraitUp].
landscapeRight,
参考:https://greymag.medium.com/flutter-orientation-lock-portrait-only-c98910ebd769
在 activity 标签下主文件夹中的 AndroidManifest 文件中设置 android:screenOrientation = "portrait"
<activity android:windowSoftInputMode="adjustResize" android:screenOrientation = "portrait">
在GetX中,你需要像这个例子一样使用GetBuilder:
final Controller ctrl = Get.find();
GetBuilder<Controller>(
initState: (_) => ctrl.setLandscape(),
dispose: (_) => ctrl.setPortrait(),
builder: (code) => Container(
padding: const EdgeInsets.zero,
alignment: Alignment.Center,
child: const SizedBox(),
),
),
In Controller file:
class Controller extends GetxController {
RxBool isLandscape = false.obs;
Future<void> setLandscape() async {
if (isLandscape.isTrue) {
await SystemChrome.setPreferredOrientations([DeviceOrientation.landscapeLeft]);
update();
}
}
Future<void> setPortrait() async {
if (isLandscape.isFalse) {
await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
update();
}
}
}