原生端与Flutter的通信

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

基本元素

自定义的页面
基本功能学习
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,529评论 5 475
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,015评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,409评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,385评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,387评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,466评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,880评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,528评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,727评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,528评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,602评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,302评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,873评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,890评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,132评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,777评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,310评论 2 342

推荐阅读更多精彩内容