Flutter 之和原生交互

作者: 代瑶 | 来源:发表于2020-07-08 16:18 被阅读0次

    先盗一张图

    image.png

    我们需要实现的效果

    • Flutter 传输数据到 Android Native
    • Flutter 跳转到Android Native界面
    • Android Native 给 Flutter 传输数据
    GIF 2020-7-8 15-56-45.gif

    看GIF图
    第一项按钮点击跳转到原生Activity 后,点击中间文字会改变测试界面的第三项按钮文字。

    第二项点击后是Flutter 传递到原生界面的一个Map数据

    我们来看代码实现。

    首先Flutter代码

    import 'dart:async';
    
    import 'package:flutter/cupertino.dart';
    import 'package:flutter/material.dart';
    import 'package:flutter/services.dart';
    
    void main() {
      runApp(MaterialApp(
        home: Scaffold(
          appBar: AppBar(
            title: Text('测试界面'),
          ),
          body: TestWidget(),
        ),
      ));
    }
    
    class TestWidget extends StatefulWidget {
      @override
      State<StatefulWidget> createState() {
        return TestState();
      }
    }
    
    class TestState extends State<TestWidget> {
      //获取插件与原生Native的交互通道
      static const sendToNative = const MethodChannel('com.guoteng.native.receive/plugin');
    
      //具体要做的功能
      Future<Null> _startToNativeActivity() async {
        String result = await sendToNative.invokeMethod('startToEditActivity');
        print(result);
      }
    
      // 具体要做的功能
      Future<Null> _sendDataToNative() async {
        Map<String, String> map = {"flutter": "我是flutter 传递过来的"};
        String result = await sendToNative.invokeMethod('mapData', map);
        print(result);
      }
    
      //接收来自本地的消息
      static const receiveFromNative = const EventChannel('com.guoteng.native.send/plugin');
      StreamSubscription _streamSubscription;
      var _currentCount;
    
      @override
      void initState() {
        super.initState();
        //开启监听
        if (_streamSubscription == null) {
          _streamSubscription = receiveFromNative.receiveBroadcastStream().listen((Object event) {
            setState(() {
              _currentCount = event;
              print("ChannelPage: $event");
            });
          }, onError: (Object error) {
            setState(() {
              _currentCount = "计时器异常";
              print(error);
            });
          });
        }
      }
    
      @override
      void dispose() {
        super.dispose();
        //取消监听
        if (_streamSubscription != null) {
          _streamSubscription.cancel();
        }
      }
    
      @override
      Widget build(BuildContext context) {
        return Container(
            child: Column(
          children: <Widget>[
            RaisedButton(
              child: Text('跳转到原生activity'),
              onPressed: () {
                _startToNativeActivity();
              },
            ),
            RaisedButton(
              child: Text('让原生接收到数据'),
              onPressed: () {
                _sendDataToNative();
              },
            ),
            RaisedButton(
              child: Text('原生传递过来的值$_currentCount'),
              onPressed: () {},
            )
          ],
        ));
      }
    }
    
    

    android 端 MainActivity 代码

    package com.example.flutterapp
    
    import android.os.Bundle
    import io.flutter.app.FlutterActivity //这里注意,使用io.flutter.app下的FlutterActivity
    
    class MainActivity : FlutterActivity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
    
            //获取到自身的Registry
            val registry = flutterView.pluginRegistry;
            //注册插件
            FlutterPluginFtoA.registerWith(registry.registrarFor(FlutterPluginFtoA.A_TO_F_CHANNEL));
            FlutterPluginAtoF.registerWith(registry.registrarFor(FlutterPluginAtoF.F_TO_A_CHANNEL));
        }
    }
    
    
    package com.example.flutterapp;
    
    import android.app.Activity;
    
    import io.flutter.plugin.common.EventChannel;
    import io.flutter.plugin.common.PluginRegistry;
    
    /**
     * android 本地代码传数据到Flutter
     */
    public class FlutterPluginAtoF implements EventChannel.StreamHandler {
        public static final String F_TO_A_CHANNEL = "com.guoteng.native.send/plugin";
        private static FlutterPluginAtoF instance;
        private EventChannel.EventSink events;
    
        public static FlutterPluginAtoF getInstance() {
            return instance;
        }
    
    
        public static void registerWith(PluginRegistry.Registrar registrar) {
            EventChannel eventChannel = new EventChannel(registrar.messenger(), F_TO_A_CHANNEL);
            instance = new FlutterPluginAtoF();
            eventChannel.setStreamHandler(instance);
        }
    
    
        @Override
        public void onListen(Object arguments, EventChannel.EventSink events) {
            this.events = events;
        }
    
        @Override
        public void onCancel(Object arguments) {
    
        }
    
        public void sendEventData(Object data){
            if(events != null){
                events.success(data);
            }
        }
    }
    
    
    package com.example.flutterapp;
    
    import android.app.Activity;
    import android.content.Intent;
    import android.widget.Toast;
    
    import androidx.annotation.NonNull;
    
    import io.flutter.plugin.common.MethodCall;
    import io.flutter.plugin.common.MethodChannel;
    import io.flutter.plugin.common.PluginRegistry;
    
    /**
     * 从Flutter传递到本地的插件类
     */
    public class FlutterPluginFtoA implements MethodChannel.MethodCallHandler {
        //这里要注意和Flutter使用的相同
        public static final String A_TO_F_CHANNEL = "com.guoteng.native.receive/plugin";
        private Activity handlerActivity;
    
        public FlutterPluginFtoA(Activity activity) {
            this.handlerActivity = activity;
        }
    
        public static void registerWith(PluginRegistry.Registrar registrar) {
            //主要的方法MethodChannel
            MethodChannel methodChannel = new MethodChannel(registrar.messenger(), A_TO_F_CHANNEL);
            FlutterPluginFtoA instance = new FlutterPluginFtoA(registrar.activity());
            methodChannel.setMethodCallHandler(instance);
        }
    
        /**
         * @param call  回调过来的Flutter 的方法 和 参数
         * @param result  通过result 可以返回数据给Flutter
         */
        @Override
        public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
            //和原生交互返回
            switch (call.method) {
                case "showToast":
                    //接收Flutter 传递过来的参数
                    Object arguments = call.arguments;
                    Toast.makeText(handlerActivity, "收到Flutter传过来的" + arguments, Toast.LENGTH_SHORT).show();
                    break;
                case "startToEditActivity":
                    //跳转到原生界面
                    Intent editActivityIntent = new Intent(handlerActivity, EditH5Activity.class);
                    handlerActivity.startActivity(editActivityIntent);
    
                    result.success("startOk");
                    break;
                case "mapData":
                    //Flutter 传递过来的数据
                    //解析参数
                    String text = call.argument("flutter");
                    Toast.makeText(handlerActivity, "接收: " + text, Toast.LENGTH_SHORT).show();
                    break;
                default:
                    break;
            }
        }
    }
    
    

    Flutter 跳转到Native的界面代码

    package com.example.flutterapp
    
    import android.app.Activity
    import androidx.appcompat.app.AppCompatActivity
    import android.os.Bundle
    import android.view.View
    import android.widget.TextView
    
    class EditH5Activity : Activity() {
        private var currentCount = 0;
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_edit_h5)
    
            val tvIntentTxt = findViewById<TextView>(R.id.tvIntentTxt)
            tvIntentTxt.setOnClickListener(View.OnClickListener {
                FlutterPluginAtoF.getInstance().sendEventData(""+ currentCount++); //通过这个发送消息到Flutter
            })
        }
    }
    

    相关文章

      网友评论

        本文标题:Flutter 之和原生交互

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