Flutter

原生端与Flutter的通信

2020-12-31  本文已影响0人  Baffin

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

上一篇下一篇

猜你喜欢

热点阅读