Flutter为了更好的活着

Flutter 之和原生交互

2020-07-08  本文已影响0人  代瑶

先盗一张图

image.png

我们需要实现的效果

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
        })
    }
}
上一篇 下一篇

猜你喜欢

热点阅读