ios与flutter的通信
一.Flutter 加载ios原生View
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 {
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 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 creationParams = (Map) args;
return new NativeView(context, id, creationParams);
}
}
3.创建注册工具类
public class NativePlugin implements FlutterPlugin {
@Override
public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) {
binding.getPlatformViewRegistry().registerViewFactory("", 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