最近做一個ios項目,裏面涉及了google地圖,flutter也有控件顯示google地圖,但是這些插件並不能在地圖上繪製形狀和線條,本人安卓屌絲一枚,不會用oc或者swift開發原生項目,不過我會flutter,swift還和kotlin有點像,想想好像可以應對,就決定用flutter開發界面,然後調用原生的google地圖控件
這就開始了 flutter調用第三方(googleMap)控件的歷程
另外附上我查看過的,有用的資料(包括Android)
Flutter之在Flutter佈局中嵌入原生組件Android篇
創建一個Flutter插件,使用PlatformView顯示iOS的本機視圖
第一步:在info.plist裏面添加如下代碼(這是最重要的一步,所以先說,我上次就是吃了這虧,就差這沒寫,找了半天的問題)
<key>io.flutter.embedded_views_preview</key>
<true/>
第二步:寫你要調用的控件
要注意的是 你的控件必須繼承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