1.原生的向fluter 也页面传值
首先需要在flutter 引入
import 'dart:ui';
引入以后我们可以取到 window,window含有一个window.defaultRouteName属性
那么这个属性在iOS原生工程的FlutterViewController类有一个与之对应的方法
/**
- Sets the first route that the Flutter app shows. The default is "/".
- This method will guarnatee that the initial route is delivered, even if the
- Flutter window hasn't been created yet when called. It cannot be used to update
- the current route being shown in a visible FlutterViewController (see pushRoute
- and popRoute).
- @param route The name of the first route to show. */
- (void)setInitialRoute:(NSString*)route;
我的测试代码 iOS
FlutterViewController * flutterVc = [[FlutterViewController alloc] init];
[flutterVc setInitialRoute:@"wincer"];
[self presentViewController:flutterVc animated:YES completion:^{
}];
Flutter 代码
import 'package:flutter/material.dart'; import 'dart:ui';
void main() => runApp(MyApp(pageIndex:window.defaultRouteName));
class MyApp extends StatelessWidget { final String pageIndex;
const MyApp({Key key, this.pageIndex}) : super(key: key); // This widget is the root of your application. @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( // This is the theme of your application. // // Try running your application with "flutter run". You'll see the // application has a blue toolbar. Then, without quitting the app, try // changing the primarySwatch below to Colors.green and then invoke // "hot reload" (press "r" in the console where you ran "flutter run", // or press Run > Flutter Hot Reload in a Flutter IDE). Notice that the // counter didn't reset back to zero; the application is not restarted. primarySwatch: Colors.blue, ), home: rootpage(pageIndex) , ); } }
Widget rootpage(String pageIndex){
** print(pageIndex);** return Container( ** child: Text(pageIndex)**
); }
flutter 代码加载的部分为我更改的,你可以与源代码比较
效果图
flutter 的打印在xcode可以看到
我们正常的混合开发肯定是需要某些页面是flutter写的,那么我们可以根据window.defaultRouteName这个去指定调到那个页面
2.返回到原生
现在我们可以跳到flutter ,我们也需要跳回去
那么就需要在flutter 引入 import 'package:flutter/services.dart';
这个service 含有一个channel,我们就是根据这个channel去和iOS原生通讯了! const MethodChannel(this.name, [this.codec = const StandardMethodCodec()]); 这个channel 有两个参数,第一是name,这个name就是一个标识符,唯一的 codec就是是否不要进行类型转换的!比如flutter 的string 转换成iOS 的NSString
MethodChannel这个方法相当于我们的通知,在iOS内也需要注册下
那么这 MethodChannel 改怎么发送通知呢? MethodChannel('wincer_flutter').invokeMapMethod(method) 后面的method相当于我们iOS的Sel
这个method 就是调用我们原生的方法,如果需要参数,后面可以加上参数,用,分割
Flutter示例代码 MethodChannel('wincer_flutter').invokeMapMethod('
','13123123');那么我们在iOS也需要创建一个 FlutterMethodChannel
FlutterMethodChannel * methodChennel = [FlutterMethodChannel methodChannelWithName:@"wincer_flutter" binaryMessenger:flutterVc];
withName的参数就是flutter channel 的name, binaryMessenge:就是创建的flutterVC
那么这个FlutterMethodChannel有一个句柄, [methodChennel setMethodCallHandler:^(FlutterMethodCall * _Nonnull call, FlutterResult _Nonnull result) { NSLog(@"%@\n%@",call.method,call.arguments); }];
我们可以看到block回调内有有个call,call有两个信息 call.method 方法名字 call.arguments flutter传的参数
这样我们就可以根据获取到的call.methond 进行我们想做的操作了!
==========================================
我们可以猜想下,FlutterMethodChannel 可以用于flutter给iOS传参,那么这个东西是不是也可以用于iOS给flutter 传参呢!
这两个平台的使用 FlutterMethodChannel完全一样,
ios 原生向flutter 传值 于flutter向原生类似。
FlutterMethodChannel * methodChennel = [FlutterMethodChannel methodChannelWithName:@"wincer_flutter" binaryMessenger:flutterVc];
[methodChennel invokeMethod:@"onePage" arguments:nil];
flutter接收也是类似
final MethodChannel _oneChanel = MethodChannel('onePage');
_oneChanel.setMethodCallHandler((MethodCall call){ _pageIndex = call.method; setState(() {
});
}
对比下,是不是完全相同,
但是此时我发现一个问题,跳进flutter ,然后退出到原生,再跳flutter ,内存只增不减,
其实我这里是FlutterViewController写成了局部变量,这个东西不会释放的,而且整个flutter在我们原生里只有一个FlutterViewController就够用了!所以开发时候只需创建一个就可以了
写的比较粗糙,比较乱,如有需要评论,我会主动联系你的
喷我的直接评论就好了!