初始化Engines
/* APP冷启动之后 */
[[MKFlutterEngineMgr sharedInstance] initEngines];
- (void)initEngines {
// 多个tab页多个引擎,二级页复用单引擎
NSMutableArray* mArr = [NSMutableArray arrayWithCapacity:2];
for (int i=0; i<2; i++) {
FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"ios_flutter" project:nil];
[engine runWithEntrypoint:nil];
[MKPluginRegistrant registerWithRegistry:engine];
[mArr addObject:engine];
}
self.flutterEngines = mArr;
}
创建FlutterViewController
/* 基于BaseVC的ShowFlutterVC */
FlutterEngine* flutterEngine = [[[MKFlutterEngineMgr sharedInstance] flutterEngines] objectAtIndex:_tabIndex];
self.flutterVC = [[MKFlutterViewController alloc] initWithEngine:flutterEngine nibName:nil bundle:nil];
self.flutterVC.routeName = _routeName;
通过routeChannel配置路由信息
static NSString * const kFlutterRouteChannelName = @"com.base.test/route";
- (void)initData {
/* 默认都是StandardCodec,Codec需要保持与flutter端一致 */
self.routeChannel = [FlutterMethodChannel methodChannelWithName:kFlutterRouteChannelName binaryMessenger:[self binaryMessenger]];
}
- (void)setRouteName:(NSString *)routeName {
_routeName = [routeName copy];
[self invokeRoute:@"InitialRoute" arguments:@{@"route":routeName}];
}
- (void)invokeRoute:(NSString*)method arguments:(id _Nullable)arguments {
[self.routeChannel invokeMethod:method arguments:arguments result:^(id _Nullable result) {
}];
}
- (BOOL)loadDefaultSplashScreenView {
return NO;
}
初始化FlutterBridge,实现通知的监听
- (void)initData {
self.flutterBridge = [[MKFlutterBridgeHandle alloc] initWithContainer:self];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(becomeActiveHandle:) name:UIApplicationDidBecomeActiveNotification object:nil];
}
- (void)becomeActiveHandle:(NSNotification *)notification {
[self.flutterBridge sendMessageName:@"didBecomeActiveNotification" args:nil];
}
FlutterBridge的具体实现
- (void)initChannels {
/* 默认都是StandardCodec,Codec需要保持与flutter端一致 */
self.baseMessageChannel = [FlutterBasicMessageChannel messageChannelWithName:kFlutterMessagehannelName binaryMessenger:[self.container binaryMessenger]];
self.methodChannel = [FlutterMethodChannel methodChannelWithName:kFlutterMethodChannelName binaryMessenger:[self.container binaryMessenger]];
/* flutter调用native方法 */
[self.methodChannel setMethodCallHandler:^(FlutterMethodCall * _Nonnull call, FlutterResult _Nonnull result) {
if(!call.arguments && !call.method) {
result(FlutterMethodNotImplemented);
return;
}
NSString *method = (NSString *)call.method;
NSDictionary *arguments = (NSDictionary *)call.arguments;
NSLog(@"method:%@; arguments:%@", method, arguments);
result(@"{\"key\":\"value\"}");
}];
}
/* native调用flutter方法 */
- (void)invokeFlutterMethod:(NSString *)method arguments:(NSString *)arguments result:(FlutterResult )callback {
[self.methodChannel invokeMethod:method arguments:arguments result:callback];
}
/* 广播 */
- (void)sendMessageName:(NSString *)messageName args:(id _Nullable)arguments {
[self.baseMessageChannel sendMessage:@{@"messageName": messageName, @"arguments": arguments?arguments:@""}];
}
FlutterPlugin的具体应用
/* 创建FlutterPlugin */
@interface MKFlutterReportPlugin : NSObject
@end
static NSString * const kFlutterReportChannelName = @"com.base.test/report";
@implementation MKFlutterReportPlugin
+ (void)registerWithRegistrar:(NSObject *)registrar {
FlutterMethodChannel *channel = [FlutterMethodChannel methodChannelWithName:kFlutterReportChannelName binaryMessenger:[registrar messenger]];
MKFlutterReportPlugin *instance = [[MKFlutterReportPlugin alloc] init];
[registrar addMethodCallDelegate:instance channel:channel];
}
- (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result {
NSLog(@"--futter -- call -- method :%@ arguments:%@",call.method,call.arguments);
}
@end
/* 注册FlutterPlugin */
@interface MKPluginRegistrant : GeneratedPluginRegistrant
@end
@implementation MKPluginRegistrant
+ (void)registerWithRegistry:(NSObject *)registry {
[super registerWithRegistry:registry];
[MKFlutterLogPlugin registerWithRegistrar:[registry registrarForPlugin:@"LCFlutterReportPlugin"]];
}
@end
从main函数配置routeChannel,实现路由切换
final t_methodChannel = const MethodChannel('com.base.test/route');
void main() {
WidgetsFlutterBinding.ensureInitialized();
t_methodChannel.setMethodCallHandler(platformCallHandler);
}
Future platformCallHandler(MethodCall call) async {
print("Flutter---" + call.arguments['route']);
if (call.method == 'InitialRoute') {
runApp(EnterApp(call.arguments['route']));
}
return '';
}
class EnterApp extends StatefulWidget {
String _routeName;
EnterApp(this._routeName);
EnterAppState createState() => EnterAppState();
}
class EnterAppState extends State {
@override
Widget build(BuildContext context) {
Map routeDic = {
"/myApp": MyAppPage(),
"/home": MyHomePage()
};
print('EnterAppState ===== build ${widget._routeName}');
return new MaterialApp(
title: '测试',
initialRoute: widget._routeName,
home: routeDic[widget._routeName],
/*
routes: {
"/myApp": (context) => MyAppPage(),
"/home": (context) => MyHomePage()
}
*/
);
}
}
MyAppPage代码示例
import 'package:flutter/material.dart';
import 'dart:ui' as ui;
final double kScreenWidth = ui.window.physicalSize.width/ui.window.devicePixelRatio;
final double kScreenHeight = ui.window.physicalSize.height/ui.window.devicePixelRatio;
final double kScreenScale = ui.window.devicePixelRatio;
class MyAppPage extends StatefulWidget {
@override
_MyAppPage createState() => _MyAppPage();
}
class _MyAppPage extends State {
static String picUrl = 'http://attachments.gfan.com/forum/201606/25/0001033cc0l90arrt1sf3a.jpg';
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("首页"),
backgroundColor: Color.fromRGBO(100, 100, 100, 1)
),
drawer: Drawer(
child: ListView(
scrollDirection: Axis.vertical,
itemExtent: 60,
children: List.generate(50, (index){
return Container(
alignment: Alignment.center,
child: Column(
mainAxisAlignment: MainAxisAlignment.start ,
children: [Text("行数 $index", style: TextStyle(fontSize: 18))]
)
);
}))
),
bottomNavigationBar: BottomNavigationBar(
items: [
BottomNavigationBarItem(icon: Icon(Icons.home, color: Colors.blue), title: Text('首页', style: TextStyle(color: Colors.blue),)),
BottomNavigationBarItem(icon: Icon(Icons.shop, color: Colors.black), title: Text('购物', style: TextStyle(color: Colors.black),))
],
onTap: (index) {
print('tabIndex $index');
}
),
body: Center(
child: ListView(
padding: EdgeInsets.all(0),
children: List.generate(8, (index){
return Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
FlatButton(onPressed: () {
print('文字 index:${index+1}');
}, child: Text('文字 index:${index+1}', textAlign: TextAlign.left,), padding: EdgeInsets.all(10),),
Icon(Icons.subway, color: Colors.blue, size: 24, textDirection: TextDirection.ltr),
]
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
FlatButton(onPressed: () {
print('图片 index:${index+1}');
}, child: Image.network(picUrl,
height: 200, width: kScreenWidth - 20,
fit: BoxFit.fill,),
padding: EdgeInsets.only(left: 10, right: 10),),
]
)
],
);
})
)
)
);
}
}
下载地址:https://github.com/zhengmiaokai/Flutter-IOS