Flutter笔记 02:iOS调用多个flutter界面

需求

flutter需要调用多个Flutter界面,且需要传输数据到flutter

问题

由于最开始的与iOS的混编,是只调用一个界面,而现在需要调用多个。所以这里我们是通过FlutterEngine初始化FlutterViewController,并通过设置setInitialRoute设置初始化路由,以下是交互的代码

 

<!--OC代码-->
//通过engine创建flutter界面
FlutterEngine flutterEngine = [[FlutterEngine alloc] initWithName:@"flutter engine"];
[flutterEngine run];
FlutterViewController *flutterVC = [[FlutterViewController alloc] initWithEngine:flutterEngine nibName:nil bundle:nil];

//设置路由
[flutterVC setInitialRoute:@"message"];

//消息传递通道,native传递到flutter
FlutterMethodChannel *flutterChannel = [FlutterMethodChannel methodChannelWithName:@"nativeToFluuter" binaryMessenger:flutterVC.binaryMessenger];
[flutterChannel invokeMethod:@"message" arguments:@{@"message":@"hello world"}];

[self.navigationController pushViewController:flutterVC animated:YES];

<!--Flutter代码-->
void main() => runApp(_widgetForRoute(ui.window.defaultRouteName));

Widget _widgetForRoute(String route){
switch (route){
case 'message':
return MyApp();
case 'other':
return OtherPage();
default:
return DefaultPage();
}
}

但是通过实测发现,setInitialRoute设置的路由并不生效,在flutter端通过 window.defaultRouteName拿到的route永远是/根符号。这个是Flutter SDK的一个bug

解决办法有以下几种

方式1 -

如果必须使用setInitialRoute来区分不同的flutter界面,那么就不能通过FlutterEngine初始化FlutterViewController,需要直接使用 alloc+init 或者 new 的方式初始化FlutterViewController。

注:这种方式有一个问题,每次渲染会有启动页一闪而过的效果,且这种方式初始化的FlutterViewController在关闭时是无法释放内存的

改进后的代码如下所示

 

<!--OC代码-->
//通过alloc+init创建flutter界面
FlutterViewController *flutterVC = [[FlutterViewController alloc] init];

//设置路由
[flutterVC setInitialRoute:@"message"];

//消息传递通道,native传递到flutter
FlutterMethodChannel *flutterChannel = [FlutterMethodChannel methodChannelWithName:@"nativeToFluuter" binaryMessenger:flutterVC.binaryMessenger];
[flutterChannel invokeMethod:@"message" arguments:@{@"message":@"hello world"}];

[self.navigationController pushViewController:flutterVC animated:YES];

<!--Flutter代码-->
void main() => runApp(_widgetForRoute(ui.window.defaultRouteName));

Widget _widgetForRoute(String route){
switch (route){
case 'message':
return MyApp();
case 'other':
return OtherPage();
default:
return DefaultPage();
}
}

方式2

通过FlutterMethodChannel传入的method进行区分,以下是代码逻辑

 

<!--OC代码-->
//通过alloc+init创建flutter界面
FlutterViewController *flutterVC = [[FlutterViewController alloc] init];

//消息传递通道,native传递到flutter
FlutterMethodChannel *flutterChannel = [FlutterMethodChannel methodChannelWithName:@"nativeToFluuter" binaryMessenger:flutterVC.binaryMessenger];
[flutterChannel invokeMethod:@"message" arguments:@{@"message":@"hello world"}];

[self.navigationController pushViewController:flutterVC animated:YES];

<!--Flutter代码-->
void main() => runApp(MyApp());

class MyApp extends StatefulWidget {

@override
_MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
//用于区分不同界面
String pageRoute;
dynamic arguments;

@override
void initState() {
super.initState();

ConstantsUtil.nativeToFlutterChannel.setMethodCallHandler((call) {
setState(() {
pageRoute = call.method;
arguments = call.arguments;
});
return null;
});

}

@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: rootPage(pageRoute),
);
}

rootPage(String route){
switch (route){
case 'message':
return MessagePage(title: 'Message', arguments: arguments,);
case 'other':
return OtherPage(title: 'Other', arguments: arguments,);
default:
return DefaultPage();
}
}
}

 

0人点赞

 

Flutter学习笔记

 

 

上一篇:算法学习记录005_寻找字符串中连续最长字符以及个数


下一篇:计算广告-视频学习-随笔-005