美文网首页Flutter
原生端与Flutter的通信

原生端与Flutter的通信

作者: Baffin | 来源:发表于2020-12-31 09:24 被阅读0次

    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的通信

        本文链接:https://www.haomeiwen.com/subject/jqlloktx.html