ios與flutter的通信
一.Flutter 加載ios原生View
通信.gif
1.xcode中創建ios View
此 View 繼承 FlutterPlatformView
class FristView: NSObject,FlutterPlatformView {
let label = UILabel()
init(_ frame: CGRect,viewID: Int64,args :Any?,messenger :FlutterBinaryMessenger) {
super.init()
if(args is NSDictionary){
let dict = args as! NSDictionary
let pramaValue:String = dict.value(forKey: "text") as! String;
let viewId:Int = Int(viewID)
label.font = .systemFont(ofSize: 14)
label.numberOfLines = 0
label.text = "參數:\(pramaValue),\nviewID:\(viewId)"
}
}
func view() -> UIView {
return label
}
}
2.創建工廠類,關聯view
class FristViewFactory: NSObject,FlutterPlatformViewFactory {
var messenger:FlutterBinaryMessenger
init(messenger:FlutterBinaryMessenger) {
self.messenger = messenger
super.init()
}
func create(withFrame frame: CGRect, viewIdentifier viewId: Int64, arguments args: Any?) -> FlutterPlatformView {
return FristView(frame,viewID: viewId,args: args,messenger: messenger)
}
func createArgsCodec() -> FlutterMessageCodec & NSObjectProtocol {
return FlutterStandardMessageCodec.sharedInstance()
}
}
3.注冊這個平臺視圖
一步可以在應用中,也可以在插件中,這里除了在應用中注冊,也就是修改應用中的 AppDelegate.swift
//加載原生視圖
let fristRegistrar:FlutterPluginRegistrar = self.registrar(forPlugin: "FristView")!;
let fristFactory = FristViewFactory(messenger: fristRegistrar.messenger())
fristRegistrar.register(fristFactory, withId: "FristView");
4.flutter中的處理
在一個Widget中添加如下代碼:
UiKitView(
viewType: 'FristView',
creationParams: {'text': 'Flutter傳給ios的參數'},
onPlatformViewCreated: (viewId) {
platforms
.add(MethodChannel('com.flutter.guide.MyFlutterView_$viewId'));
},
creationParamsCodec: StandardMessageCodec(),
),
二、flutter向原生發出通信
1.創建原生視圖
這里需要打開通道methodChannel
class SecendView: NSObject,FlutterPlatformView {
let label = UILabel()
var methodChannel = FlutterMethodChannel()
init(_ frame: CGRect,viewID: Int64,args :Any?,messenger :FlutterBinaryMessenger) {
super.init()
if(args is NSDictionary){
let dict = args as! NSDictionary
let pramaValue:String = dict.value(forKey: "text") as! String;
let viewId:Int = Int(viewID)
label.font = .systemFont(ofSize: 14)
label.numberOfLines = 0
label.text = "參數:\(pramaValue),\nviewID:\(viewId)"
}
//開啟通道(加載同一個viewType時,可根據viewID對view進行判斷)
methodChannel = FlutterMethodChannel(name: "SecendView_\(viewID)", binaryMessenger: messenger)
//接收值
methodChannel.setMethodCallHandler { (call, result:FlutterResult) in
if (call.method == "getData") {
if let dict = call.arguments as? Dictionary<String, Any> {
let name:String = dict["name"] as? String ?? ""
result(["name":name])
self.label.text = "hello,\(name)"
}
}
}
}
func view() -> UIView {
return label
}
}
2.創建工廠類
class SecendViewFactory: NSObject,FlutterPlatformViewFactory {
var messenger:FlutterBinaryMessenger
init(messenger:FlutterBinaryMessenger) {
self.messenger = messenger
super.init()
}
func create(withFrame frame: CGRect, viewIdentifier viewId: Int64, arguments args: Any?) -> FlutterPlatformView {
return SecendView(frame,viewID: viewId,args: args,messenger: messenger)
}
func createArgsCodec() -> FlutterMessageCodec & NSObjectProtocol {
return FlutterStandardMessageCodec.sharedInstance()
}
}
3.在AppDelegate中注冊平臺視圖
//flutter向原生視圖傳遞
let secendRegistrar:FlutterPluginRegistrar = self.registrar(forPlugin: "SecendView")!;
let secendFactory = SecendViewFactory(messenger: secendRegistrar.messenger())
secendRegistrar.register(secendFactory, withId: "SecendView");
4.flutter調用
通過RaisedButton點擊,將值傳個原生View
Container(
child: Column(
children: [
Container(
color: Colors.lightBlue,
height: 80,
child: UiKitView(
viewType: 'SecendView',
creationParams: {'text': 'Flutter通過事件傳參數給原生View'},
onPlatformViewCreated: (viewId) {
platforms.add(MethodChannel('SecendView_$viewId'));
},
creationParamsCodec: StandardMessageCodec(),
),
),
RaisedButton(
child: Text('傳遞參數給原生View'),
onPressed: () async {
var result =
await platforms[1].invokeMethod('getData', {'name': '鴻億'});
print("$result");
},
),
],
),
height: 150,
)
三、原生向flutter傳遞
1.創建原生view
這里創建一個button進行點擊
class ThreeView: NSObject,FlutterPlatformView {
let button = UIButton()
var methodChannel = FlutterMethodChannel()
init(_ frame: CGRect,viewID: Int64,args :Any?,messenger :FlutterBinaryMessenger) {
super.init()
button.setTitle(("點擊傳遞參數給flutter"), for: .normal)
button.addTarget(self, action: #selector(click), for: .touchUpInside)
methodChannel = FlutterMethodChannel(name: "ThreeView_MethodChannel", binaryMessenger: messenger)
}
@objc func click() {
NSLog("點擊了按鈕")
methodChannel.invokeMethod("sendToFlutter", arguments:["param":"原生傳遞的數據"])
}
func view() -> UIView {
return button
}
}
2.創建工廠類
class ThreeViewFactory: NSObject,FlutterPlatformViewFactory {
var messenger:FlutterBinaryMessenger
init(messenger:FlutterBinaryMessenger) {
self.messenger = messenger
super.init()
}
func create(withFrame frame: CGRect, viewIdentifier viewId: Int64, arguments args: Any?) -> FlutterPlatformView {
return ThreeView(frame,viewID: viewId,args: args,messenger: messenger)
}
func createArgsCodec() -> FlutterMessageCodec & NSObjectProtocol
}
3.注冊
//原生視圖向flutter傳遞
let threeRegistrar:FlutterPluginRegistrar = self.registrar(forPlugin: "ThreeView")!;
let threeFactory = ThreeViewFactory(messenger: threeRegistrar.messenger())
threeRegistrar.register(threeFactory, withId: "ThreeView");
4.flutter調用
//通訊通道
var channel = MethodChannel('ThreeView_MethodChannel');
//點擊原生視圖的回調
channel.setMethodCallHandler((call) {
print("原生->flutter${call.arguments}");
showToast("原生->flutter${call.arguments}");
});
//加入UiKitView
UiKitView(
viewType: 'ThreeView',
creationParamsCodec: StandardMessageCodec(),
),
安卓與flutter的通信
加載安卓視圖
1.在Android Studio中創建Android View
該view繼承自PlatformView
class NativeView implements PlatformView {
private final TextView textView;
NativeView(Context context, int id, Map<String, Object> creationParams) {
textView = new TextView(context);
textView.setTextSize(16);
textView.setBackgroundColor(Color.rgb(233, 105, 64));
textView.setText("安卓原生視圖 (id: " + id + ")\n "+ creationParams +"");
}
@Override
public View getView() {
return textView;
}
@Override
public void dispose() {}
}
2.創建工廠類
class NativeViewFactory extends PlatformViewFactory {
private final BinaryMessenger messenger;
public NativeViewFactory(BinaryMessenger messenger) {
super(StandardMessageCodec.INSTANCE);
this.messenger = messenger;
}
@Override
public PlatformView create(Context context, int id, Object args) {
final Map<String, Object> creationParams = (Map<String, Object>) args;
return new NativeView(context, id, creationParams);
}
}
3.創建注冊工具類
public class NativePlugin implements FlutterPlugin {
@Override
public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) {
binding.getPlatformViewRegistry().registerViewFactory("<platform-view-type>", new NativeViewFactory(binding.getBinaryMessenger()));
}
@Override
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
}
}
4.在MainActivity中調用工具類注冊
public class MainActivity extends FlutterActivity {
@Override
public void onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) {
super.onCreate(savedInstanceState, persistentState);
}
@Override
public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
super.configureFlutterEngine(flutterEngine);
flutterEngine.getPlugins().add(new NativePlugin());
}
}
5.flutter調用
調用AndroidView
AndroidView(
viewType: 'plugins.flutter.io/custom_platform_view',
//原生組件注冊名稱
creationParams: {'text': 'Flutter傳給AndroidTextView的參數'},
//傳入了一個map參數,并由原生組件接收
creationParamsCodec: const StandardMessageCodec(), //傳入的是一個編碼對象這是固定寫法
),
整合
根據defaultTargetPlatform判斷是安卓平臺還是ios平臺
安卓:defaultTargetPlatform == TargetPlatform.android
ios:defaultTargetPlatform == TargetPlatform.ios
放一個之前自己學習時寫的Flutter demo,希望可以幫助新入門的老鐵們,有好的建議可以提一下,我們一起進步,奧利給?。?!
https://github.com/Baffin-HSL/Flutter_UI
基本元素
自定義的頁面
基本功能學習