flutter混合(iOS)开发第一步使用(Flutter_Boost)完成页面之间的跳转传值(一)
首先声明我这里使用的是Flutter_Boost
可以先去看看源码demo
简单提一下原生混合Flutter我们主要做两步,第一步在我们项目统计创建我们的Flutter_module
创建方式使用我们的终端运行
flutter create -t module (你要创建的Flutter项目名称)
这样创建的方式就类似iOS
中做cocopods
插件的方式,创建出来的项目使用AndroidStudio
是能运行的完全没有问题。
然后我的原生工程用我们的cocopods
里面有pods
了,我们在podfile
中去添加这样的代码我把我的podfile
贴出来,大家不用去那个配置那个Build Phases
里面添加什么run script
。就我这样就好了。那个Build Settings
里面的Enable Bitcode
还是要改成NO
这个不要忘记了。该说的都说完了,这就是iOS
原生这边需要配置的地方。
# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'
source 'https://github.com/CocoaPods/Specs.git'
# 添加模块所在路径
flutter_application_path = '../JWellTruck_Flutter'
load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')
target 'JWellTruck' do
# Comment the next line if you don't want to use dynamic frameworks
use_frameworks!
# Pods for JWellTruck
# 安装Flutter模块
install_all_flutter_pods(flutter_application_path)
target 'JWellTruckTests' do
inherit! :search_paths
# Pods for testing
end
target 'JWellTruckUITests' do
# Pods for testing
end
end
搞完这些我们再去AppDelegate
里面配置我们的router
let router = PlatformRouterImp.init();
FlutterBoostPlugin.sharedInstance().startFlutter(with: router, onStart: { (engine) in
});
Flutter 混合开发页面跳转的几种形式
nativeA -> flutterA -> flutterB -> nativeB -> flutterB
然后就是依次返回,这样差不多就是一个App完整的页面路由了。
这里我使用的是Swift
来做的混合开发,当然OC
也是相同的道理。
首先第一步我们混合开发一般第一步是从原生到Flutter
页面。
最重要的一点必须说明一下,我们做的时候不管是Swift
还是OC
我们都要去写一个继承FLBPlatform
的类,这里主要是做页面跳转的重要地方,包括从Flutter
传过来的数据这些我们都可以在这里拿到,这里我贴一下我的这个类,只是拿官方demo
稍微做了一点修改。主要是我自己的原生项目里面的TabBar
和Navigation
都是自定义的我的原生代码如下
import Foundation
import flutter_boost
class PlatformRouterImp: NSObject, FLBPlatform {
func open(_ url: String, urlParams: [AnyHashable : Any], exts: [AnyHashable : Any], completion: @escaping (Bool) -> Void) {
var animated = false;
if exts["animated"] != nil{
animated = exts["animated"] as! Bool;
}
let vc = FLBFlutterViewContainer.init()
vc.setName(url, params: urlParams)
vc.navigation.bar.isHidden = true
vc.hidesBottomBarWhenPushed = true
<!--这里的topVC是我项目里面写的一个获取最上层控制器的方法我也贴一下我的代码-->
topVC?.navigationController!.pushViewController(vc, animated: animated);
completion(true);
}
func present(_ url: String, urlParams: [AnyHashable : Any], exts: [AnyHashable : Any], completion: @escaping (Bool) -> Void) {
var animated = false;
if exts["animated"] != nil{
animated = exts["animated"] as! Bool;
}
let vc = FLBFlutterViewContainer.init();
vc.setName(url, params: urlParams);
topVC?.navigationController!.present(vc, animated: animated) {
completion(true);
};
}
func close(_ uid: String, result: [AnyHashable : Any], exts: [AnyHashable : Any], completion: @escaping (Bool) -> Void) {
var animated = false;
if exts["backNative"] != nil{
animated = exts["backNative"] as! Bool;
}
let presentedVC = topVC?.navigationController!.presentedViewController;
let vc = presentedVC as? FLBFlutterViewContainer;
if vc?.uniqueIDString() == uid {
vc?.dismiss(animated: animated, completion: {
completion(true);
});
}else{
topVC?.navigationController!.popViewController(animated: animated);
}
}
// func navigationController() -> UINavigationController {
// let delegate = UIApplication.shared.keyWindow?.rootViewController as! UINavigationController
//// let navigationController = delegate.window?.rootViewController as! UINavigationController
// return delegate.navigationController!
// }
}
我在我的公共类里面写了一个这样的方法(代码里面所有的属性不会存在找不到情况了)
var topVC: UIViewController? {
var resultVC: UIViewController?
resultVC = _topVC(UIApplication.shared.keyWindow?.rootViewController)
while resultVC?.presentedViewController != nil {
resultVC = _topVC(resultVC?.presentedViewController)
}
return resultVC
}
接下来我们把所有情况都分类都说一遍:
1、 Native To Flutter
Native里面的代码:
FlutterBoostPlugin.open("页面参数名,就是Flutter里面配置的这个名字,mian页面需要配置的", urlParams: ["这里是一个标识符类似标记那种"], exts: ["这里给一个参数,比如我们push的时候animated是否需要动画"], onPageFinished: { (_ result:Any?) in
print("这里是在页面打开成功后回调,这里就会把我们上那边urlParams里面的标识符传过来")
}) { (f: Bool) in
print("页面打开")
}
<!--这里是我写的值-->
FlutterBoostPlugin.open("first", urlParams:[kPageCallBackId:"HomePagecallbackId#1"], exts: ["animated":true], onPageFinished: { (_ result:Any?) in
print(String(format:"call me when page finished, and your result is:%@", result as! CVarArg));
}) { (f:Bool) in
print(String(format:"page is opened"));
}
Dart里面的代码(需要先在main
里面)我们在StatefulWidget
下搞一个:
void initState() {
super.initState();
FlutterBoost.singleton.registerPageBuilders(<String, PageBuilder>{
'first': (String pageName, Map<String, dynamic> params, String _) =>
FirstRouteWidget(),
});
}
这样就能打开一个我们的flutter
页面了。
打开时第一步,我们还要传值过去原生传值过去的代码
// 传值给Flutter
FlutterBoostPlugin.sharedInstance().sendEvent("data", arguments: ["name":"ryan","age":18])
我们在dart
里面获取值
// 监听原生传过来的值
FlutterBoost.singleton.channel.addEventListener("data", (name, arguments) {
print(arguments["age"]);
return;
});
各位大佬:小弟正在Flutter学习中,如有什么不妥的地方还望各位大佬斧正!!!
转载自:https://juejin.cn/post/6844904177022287885