Я хочу показать одну страницу в моем приложении Flutter в альбомном режиме. Все остальные экраны должны отображаться в портретном режиме.
Я нашел этот фрагмент кода:
В моем main.dart
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]).then((_) {
runApp(new IHGApp());
});
Это запустит приложение в портретном режиме. Итак, у меня есть экран, который я хочу показать в ландшафтном режиме, и вот код, который я там использовал:
@override
void initState() {
super.initState();
SystemChrome.setPreferredOrientations([
DeviceOrientation.landscapeRight,
DeviceOrientation.landscapeLeft,
]);
}
@override
void dispose() {
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]);
super.dispose();
}
Это работает на Android.
В iOS кажется, что нет возможности принудительно установить альбомный режим для одной страницы.
https://github.com/flutter/flutter/issues/13238
В этой статье я нашел проблему для этой проблемы. sroddy упомянул, как решить проблему.
«Я решил проблему, создав небольшой канал платформы, который вызывает этот код для переключения в портретную ориентацию прямо перед вызовом setPreferredOrientations:»
[[UIDevice currentDevice] setValue:@(UIInterfaceOrientationPortrait) forKey:@"orientation"];
И аналогичный код для переключения в альбомную ориентацию
[[UIDevice currentDevice] setValue:@(UIInterfaceOrientationLandscapeLeft) forKey:@"orientation"];
Как я могу реализовать это в своем приложении?





У меня было точно такое же требование в одном из моих приложений. Вам повезло - весь проект с открытым исходным кодом! Давайте сделаем это:
ios/Runner/AppDelegate.m - https://github.com/vintage/party_flutter/blob/27b11fc46755d8901f02c3b439b294ca9005277a/ios/Runner/AppDelegate.m#L8-L23#include "AppDelegate.h"
#include "GeneratedPluginRegistrant.h"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
FlutterViewController* controller = (FlutterViewController*)self.window.rootViewController;
FlutterMethodChannel* rotationChannel = [FlutterMethodChannel
methodChannelWithName:@"zgadula/orientation"
binaryMessenger:controller];
[rotationChannel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {
if ([@"setLandscape" isEqualToString:call.method]) {
[[UIDevice currentDevice] setValue:@(UIInterfaceOrientationLandscapeRight) forKey:@"orientation"];
}
else if ([@"setPortrait" isEqualToString:call.method]) {
[[UIDevice currentDevice] setValue:@(UIInterfaceOrientationPortrait) forKey:@"orientation"];
}
else {
result(FlutterMethodNotImplemented);
}
}];
[GeneratedPluginRegistrant registerWithRegistry:self];
// Override point for customization after application launch.
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
@end
MethodChannel - https://github.com/vintage/party_flutter/blob/master/lib/ui/screens/game_play.dart#L34static const _rotationChannel = const MethodChannel('zgadula/orientation');
3.initState должен вызвать поворот в альбомную ориентацию - https://github.com/vintage/party_flutter/blob/master/lib/ui/screens/game_play.dart#L71-L78
SystemChrome.setPreferredOrientations([
DeviceOrientation.landscapeRight,
]);
// TODO: Remove it when fixed in Flutter
// https://github.com/flutter/flutter/issues/13238
try {
_rotationChannel.invokeMethod('setLandscape');
} catch (error) {}
Пробный улов должен обрабатывать часть Android (такого канала нет, так как он работает, как ожидалось, без него).
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
]);
// TODO: Remove it when fixed in Flutter
// https://github.com/flutter/flutter/issues/13238
try {
_rotationChannel.invokeMethod('setPortrait');
} catch (error) {}
if (_rotateSubscription != null) {
_rotateSubscription.cancel();
}
Не стесняйтесь менять zgadula/orientation на что-то, что лучше подходит вашему проекту :)
В моем случае я сделал это без каналов. Только код Flutter.
1 шаг. Измените возможные ориентации устройства в Xcode
2-й шаг. В корневом виджете вашего приложения добавьте список ориентаций по умолчанию. Обычно это перед виджетом приложения Material.
@override
void initState() {
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
]);
super.initState();
}
Итак, теперь у нашего приложения только одна ориентация.
3-й шаг. На экране, который должен иметь другую ориентацию (например, в моем случае, полноэкранные видео), добавьте
@override
void initState() {
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.landscapeRight,
DeviceOrientation.landscapeLeft,
]);
super.initState();
}
@override
void dispose() {
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
]);
super.dispose();
}
Я попробовал канал метода, но когда я поворачиваю его, он падает. Пожалуйста, предложите мне какие-либо идеи.