最近做一个ios项目,里面涉及了google地图,flutter也有控件显示google地图,但是这些插件并不能在地图上绘制形状和线条,本人安卓屌丝一枚,不会用oc或者swift开发原生项目,不过我会flutter,swift还和kotlin有点像,想想好像可以应对,就决定用flutter开发界面,然后调用原生的google地图控件
这就开始了 flutter调用第三方(googleMap)控件的历程
另外附上我查看过的,有用的资料(包括Android)
Flutter之在Flutter布局中嵌入原生组件Android篇
创建一个Flutter插件,使用PlatformView显示iOS的本机视图
使用平台通道编写平台特定的代码
第一步:在info.plist里面添加如下代码(这是最重要的一步,所以先说,我上次就是吃了这亏,就差这没写,找了半天的问题)
io.flutter.embedded_views_preview
第二步:写你要调用的控件
要注意的是 你的控件必须继承FlutterPlatformView,请看下面代码,看完后可以照猫画虎
另外 initMethodChannel是给控件注册和原生控件通讯的渠道,和一般Channel通讯没啥区别,flutter官网有讲解的
import Flutter
import Foundation
class GoogleMapView : NSObject,FlutterPlatformView{
let frame: CGRect;
let viewId: Int64;
var messenger: FlutterBinaryMessenger!
init(_ frame: CGRect,viewID: Int64,args :Any?, binaryMessenger: FlutterBinaryMessenger) {
self.frame = frame;
self.viewId = viewID;
self.messenger=binaryMessenger;
}
func initMethodChannel(){
let googleMapChannel = FlutterMethodChannel.init(name: "samples.flutter.io/googleMap",
binaryMessenger: messenger);
googleMapChannel.setMethodCallHandler({
(call: FlutterMethodCall, result: FlutterResult) -> Void in
if(call.method == "startLoaction"){
//do something
}else if(call.method == "stopLoaction"){
}
});
}
func view() -> UIView {
initMethodChannel()
var mapView = UILabel()
mapView.text="阿姨洗吧思密达"
mapView.color=UIColor.red
mapView.frame = frame
return mapView;
}
}
第三步:创建FlutterPlatformViewFactory,还请继续照猫画虎,源码我也没看过,不知道为什么
class GoogleMapFactory : NSObject,FlutterPlatformViewFactory{
var messenger: FlutterBinaryMessenger!
func create(withFrame frame: CGRect, viewIdentifier viewId: Int64, arguments args: Any?) -> FlutterPlatformView {
return GoogleMapView(frame,viewID : viewId , args : args,binaryMessenger:messenger);
}
@objc public init(messenger: (NSObject & FlutterBinaryMessenger)?) {
super.init()
self.messenger = messenger
}
}
第四步:写一个注册控件的类,注册类是要被我们手动调用注册的!!不是系统调用!!所有flutter要调用的控件都要注册的,pluginKey是为了识别该控件有没有被注册过,属于一个标示,和调用 通信没有任何关系,而这个withId就有关系了,这个在调用控件的时候来识别调用的是哪个控件,也就是说这是控件调用的唯一识别码
class GoogleMapViewPlugin {
static func registerWith(registry:FlutterPluginRegistry) {
let pluginKey = "Google_MapView_Plugin";
if (registry.hasPlugin(pluginKey)) {return};
let registrar = registry.registrar(forPlugin: pluginKey);
let messenger = registrar.messenger() as! (NSObject & FlutterBinaryMessenger)
registrar.register(GoogleMapFactory(messenger:messenger),withId: "GoogleMapView");
}
}
最后一步,注册控件 控件注册是在AppDelegate里面的
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
//系统自带的
GeneratedPluginRegistrant.register(with: self)
//注册我们自己的控件
GoogleMapViewPlugin.registerWith(registry: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
现在 ios端的已经没什么要搞的了,下面我们调用下控件试试,看看是不是成功了呢(下面的代码我写的很简略,大家自行补齐哈)
Widget buildMapView(){
return new Container(
child: new UiKitView(viewType: "GoogleMapView"),
);
}
好了,代码就这么多,有什么问题请在下方留言哈
我的github:https://github.com/OpenFlutter/PullToRefresh;
里面有很多更酷的控件,欢迎Star;如果喜欢Flutter,可以加入我们哦,我们的QQ群是 :892398530