内容简介:我此刻的Flutter版本:Flutter 1.2.0 • channel dev •Framework • revision 06b979c4d5 (3 weeks ago) • 2019-01-25 14:27:35 -0500
我此刻的Flutter版本:
Flutter 1.2.0 • channel dev • github.com/flutter/flu…
Framework • revision 06b979c4d5 (3 weeks ago) • 2019-01-25 14:27:35 -0500
Engine • revision 36acd02c94
Tools • Dart 2.1.1 (build 2.1.1-dev.3.2 f4afaee422)
特定页面旋转屏幕很简单:
SystemChrome.setPreferredOrientations([ ... ]); 复制代码
数组中是您要支持的屏幕方向.
如果想在特定页面固定横屏, 您可以这样写:
@override
void initState() {
super.initState();
SystemChrome.setPreferredOrientations([
DeviceOrientation.landscapeRight,
DeviceOrientation.landscapeRight,
]);
}
复制代码
并且在 dispose 时更改回竖屏
@override
void dispose() {
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
]);
super.dispose();
}
复制代码
但是!!! 不要走开 本文重点在下面
在Android设备上, 调用此方法可以强制改变屏幕方向. 但在iOS上却不是这样
对于iOS, 这个方法表示设置应用支持的屏幕方向, 只有在物理方向改变时才会改变屏幕方向
现在看起来, 这应该是一个Flutter的一个Bug. 有待官方解决
您可关注 issue #13238 追踪Flutter官方的最新更新
强制改变布局方向
既然 Flutter 提供的方法不能强制改变屏幕方向, 那么我们可以通过插件的形式, 桥接到iOS原生代码中, 通过原生方式改变屏幕方向.
设置应用支持的布局方向
通过Xcode打开Flutter项目中的iOS工程, 根据下图找到 Device Orientation 这一项 勾选需要支持的布局方向, 通过这一步, 默认你现在的应用已经会根据设备的方向转变布局了
编写插件
展开 Runner / Runner 文件夹 右键->New File 添加两个新的OC文件 FlutterIOSDevicePlugin.m 和 FlutterIOSDevicePlugin.h (叫什么都没关系) 创建方式看下图:
FlutterIOSDevicePlugin.h 的内容:
#import <Flutter/Flutter.h> @interface FlutterIOSDevicePlugin : NSObject<FlutterPlugin> + (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar flutterViewController:(FlutterViewController*) controller; - (instancetype)newInstance:(NSObject<FlutterPluginRegistrar>*)registrar flutterViewController:(FlutterViewController*) controller; @end 复制代码
FlutterIOSDevicePlugin.m 的内容:
#import "FlutterIOSDevicePlugin.h"
@interface FlutterIOSDevicePlugin () {
NSObject<FlutterPluginRegistrar> *_registrar;
FlutterViewController *_controller;
}
@end
static NSString* const CHANNEL_NAME = @"flutter_ios_device";
static NSString* const METHOD_CHANGE_ORIENTATION = @"change_screen_orientation";
static NSString* const ORIENTATION_PORTRAIT_UP = @"portraitUp";
static NSString* const ORIENTATION_PORTRAIT_DOWN = @"portraitDown";
static NSString* const ORIENTATION_LANDSCAPE_LEFT = @"landscapeLeft";
static NSString* const ORIENTATION_LANDSCAPE_RIGHT = @"landscapeRight";
@implementation FlutterIOSDevicePlugin
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
FlutterMethodChannel* channel = [FlutterMethodChannel
methodChannelWithName:CHANNEL_NAME
binaryMessenger:[registrar messenger]];
FlutterIOSDevicePlugin* instance = [[FlutterIOSDevicePlugin alloc] newInstance:registrar flutterViewController:nil];
[registrar addMethodCallDelegate:instance channel:channel];
}
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar flutterViewController:(FlutterViewController*) controller {
FlutterMethodChannel* channel = [FlutterMethodChannel
methodChannelWithName:CHANNEL_NAME
binaryMessenger:[registrar messenger]];
FlutterIOSDevicePlugin* instance = [[FlutterIOSDevicePlugin alloc] newInstance:registrar flutterViewController:controller];
[registrar addMethodCallDelegate:instance channel:channel];
}
- (instancetype)newInstance:(NSObject<FlutterPluginRegistrar>*)registrar flutterViewController:(FlutterViewController*) controller{
_registrar = registrar;
_controller = controller;
return self;
}
- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
if ([METHOD_CHANGE_ORIENTATION isEqualToString:call.method]) {
NSArray *arguments = call.arguments;
NSString *orientation = arguments[0];
NSInteger iOSOrientation;
if ([orientation isEqualToString:ORIENTATION_LANDSCAPE_LEFT]){
iOSOrientation = UIDeviceOrientationLandscapeLeft;
}else if([orientation isEqualToString:ORIENTATION_LANDSCAPE_RIGHT]){
iOSOrientation = UIDeviceOrientationLandscapeRight;
}else if ([orientation isEqualToString:ORIENTATION_PORTRAIT_DOWN]){
iOSOrientation = UIDeviceOrientationPortraitUpsideDown;
}else{
iOSOrientation = UIDeviceOrientationPortrait;
}
[[UIDevice currentDevice] setValue:@(iOSOrientation) forKey:@"orientation"];
result(nil);
} else {
result(FlutterMethodNotImplemented);
}
}
@end
复制代码
注册插件
打开 AppDelegate.m 在 didFinishLaunchingWithOptions 方法中注册插件
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[GeneratedPluginRegistrant registerWithRegistry:self];
...
// flutter: Device Plugin
[FlutterIOSDevicePlugin registerWithRegistrar:[self registrarForPlugin:@"FlutterIOSDevicePlugin"] flutterViewController:controller];
}
复制代码
使用插件
import 'package:flutter/services.dart';
MethodChannel _channel = const MethodChannel('flutter_ios_device');
@override
void initState() {
super.initState();
SystemChrome.setPreferredOrientations([
DeviceOrientation.landscapeRight,
DeviceOrientation.landscapeRight,
]);
if (Platform.isIOS) {
changeScreenOrientation(DeviceOrientation.landscapeLeft);
}
}
@override
void dispose() {
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
]);
if (Platform.isIOS) {
changeScreenOrientation(DeviceOrientation.portraitUp);
}
super.dispose();
}
Future<void> changeScreenOrientation(DeviceOrientation orientation) {
String o;
switch (orientation) {
case DeviceOrientation.portraitUp:
o = 'portraitUp';
break;
case DeviceOrientation.portraitDown:
o = 'portraitDown';
break;
case DeviceOrientation.landscapeLeft:
o = 'landscapeLeft';
break;
case DeviceOrientation.landscapeRight:
o = 'landscapeRight';
break;
}
return _channel.invokeMethod('change_screen_orientation', [o]);
}
复制代码
到此, 我们的工作基本完成. 可以强制某些特定页面改变布局方向.
还没有结束
在实践中, 我发现上面这样的做法会导致一个问题.
如果只想让特定的页面可以改变方向(横屏), 其它页面一直保持竖屏该怎么办?
"图一" 中, 我们设置了 iOS 的 Device Orientation 只要设备方向改变了, 布局就会改变.
现在, 根据图一的步骤将 Device Orientation 改为 仅 Portrait
修改 AppDelegate.h , 加入 isLandscape 这个属性
@interface AppDelegate : FlutterAppDelegate @property (nonatomic,assign)BOOL isLandscape; @end 复制代码
在 AppDelegate.m 中加入下列方法
// 是否允许横屏
- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(nullable UIWindow *)window{
if (self.isLandscape) {
return UIInterfaceOrientationMaskAllButUpsideDown;
}
return UIInterfaceOrientationMaskPortrait;
}
复制代码
修改 FlutterIOSDevicePlugin.m
#import "AppDelegate.h"
- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
...
if ([orientation isEqualToString:ORIENTATION_LANDSCAPE_LEFT]){
iOSOrientation = UIDeviceOrientationLandscapeLeft;
((AppDelegate *)[UIApplication sharedApplication].delegate).isLandscape = YES;
}else if([orientation isEqualToString:ORIENTATION_LANDSCAPE_RIGHT]){
iOSOrientation = UIDeviceOrientationLandscapeRight;
((AppDelegate *)[UIApplication sharedApplication].delegate).isLandscape = YES;
}else if ([orientation isEqualToString:ORIENTATION_PORTRAIT_DOWN]){
iOSOrientation = UIDeviceOrientationPortraitUpsideDown;
((AppDelegate *)[UIApplication sharedApplication].delegate).isLandscape = NO;
}else{
iOSOrientation = UIDeviceOrientationPortrait;
((AppDelegate *)[UIApplication sharedApplication].delegate).isLandscape = NO;
}
...
}
复制代码
完成
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Beginning ASP.NET 4 in C# and Vb
Imar Spaanjaars / Wrox / 2010-3-19 / GBP 29.99
This book is for anyone who wants to learn how to build rich and interactive web sites that run on the Microsoft platform. With the knowledge you gain from this book, you create a great foundation to ......一起来看看 《Beginning ASP.NET 4 in C# and Vb》 这本书的介绍吧!