Flutter与原生安卓iOS开发交互(一)

Flutter如何嵌入到原生安卓中?

请把Flutter Dart都更新到最新版,否则网上大多数文章就不要看了,纯属浪费时间
  1. 新建一个Flutter Module
  2. 切换config为app,而非默认的main.dart
    如图:
    第一步
    在这里插入图片描述
    以上两步轻松在安卓项目中引入Flutter
    你问:如何把Flutter写的view引入到安卓中呢?
    我答:第一步在安卓端把Flutter编写的界面作为普通的view,大家都知道,安卓中能看的见的大多数控件都是view,这就很好理解了。
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
//        setContentView(R.layout.activity_main)
        // 通过FlutterView引入Flutter编写的页面
        val flutterView: View = Flutter.createView(this, lifecycle, "route1")
        val layout =
            FrameLayout.LayoutParams(600, 800)
        addContentView(flutterView, layout)

第二步在Flutter端 runApp方法里面来获取window传来的参数

void main() => runApp(_widgetForRoute(window.defaultRouteName));
Widget _widgetForRoute(String url) {

  switch (url) {
    case 'route1':
      return MaterialApp(
        home: Scaffold(
          appBar: AppBar(
            title: Text('Flutter页面'),
          ),
          body: Center(
            child: Text('Flutter页面,route=$url'),
          ),
        ),
      );

    default:
      return Center(
        child: Text('Unknown route: $url', textDirection: TextDirection.ltr),
      );
  }
}

运行后的效果:
在这里插入图片描述
如果你玩过Webview嵌套前端页面,是不是似曾相识。现在不太好看,我们稍微改一下:主题修改为NoActionBar,再把状态栏也透明起来。

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!--状态栏透明-->
        <item name="android:windowTranslucentStatus">true</item>
    </style>

再把安卓端的宽高改一下:

设置FlutterView宽高为全屏
        val layout: FrameLayout.LayoutParams = FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT)
        addContentView(flutterView, layout)

效果如图:
在这里插入图片描述
上面的方法是其中一种,还有第二种:
首先把xml里面新增一个充满父布局的Framlayout,其次通过代码替换成FlutterFragment

        // 通过FlutterFragment引入Flutter编写的页面
        val tx: FragmentTransaction = supportFragmentManager.beginTransaction()
        tx.replace(R.id.fragment, Flutter.createFragment("route1"))
        tx.commit()

好了,现在又要你问我答了.如果我想在显示Flutter写的界面的时候,传一些参数,怎么办?
我答:很简单第一步安卓端:

        /**
         * 在Flutter路由的后面跟上?+参数
         * 像不像get请求,只不过为了后面解析方便,后面跟的是json而已,其实这里我们也可以思考一下,真正的交互底层还是C/S架构的,联想一下http请求
         *
         */
        val flutterView: View = Flutter.createView(this, lifecycle,"route1?{\"name\":\"StephenCurry\"}")
        val layout: FrameLayout.LayoutParams = FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT)
        addContentView(flutterView, layout)

第二步Flutter端

Widget _widgetForRoute(String url) {


  // route名称
  String route =
  url.indexOf('?') == -1 ? url : url.substring(0, url.indexOf('?'));
// 参数Json字符串
  String paramsJson =
  url.indexOf('?') == -1 ? '{}' : url.substring(url.indexOf('?') + 1);
// 解析参数
  Map<String, dynamic> params = json.decode(paramsJson);
  print(params);

这样参数拿到了。这是FlutterView的方式传,那么FlutterFragment呢?其实是一样的。
你问我答,那如何从Flutter跳转到安卓界面呢,并且带参数

Flutter如何跳转到原生界面

安卓端编写接收代码:

class MainActivity : AppCompatActivity() {

    private val CHANNEL_NATIVE = "com.example.flutter/native"//与Flutter中channel保持一致即可

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
//        setContentView(R.layout.activity_main)


        // 通过FlutterView引入Flutter编写的页面
        val flutterView: FlutterView = Flutter.createView(this, lifecycle,"route1?{\"name\":\"StephenCurry\"}")

        val layout: FrameLayout.LayoutParams =
            FrameLayout.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT
            )
        addContentView(flutterView, layout)


        val nativeChannel = MethodChannel(flutterView, CHANNEL_NATIVE)
        nativeChannel.setMethodCallHandler { methodCall, result ->
            when (methodCall.method) {
                "jumpToNative" -> {
                    // 跳转原生页面
                    val jumpToNativeIntent = Intent(
                        this,
                        Main2Activity::class.java
                    )
                    jumpToNativeIntent.putExtra(
                        "name",
                        methodCall.argument<Any>("name") as String?
                    )
                    startActivity(jumpToNativeIntent)
                }
                else -> result.notImplemented()
            }
        }

新建一个新的Activity用于Flutter跳转过来并接收参数展示
Flutter端发送事件:

  const nativeChannel =
  const MethodChannel('com.example.flutter/native');//和原生端的ChannleName保持一致即可

    RaisedButton(
                child: Text('跳转去原生'),
                onPressed:(){
                  // 跳转原生页面
                  Map<String, dynamic> result = {'name': params['name']};//这里是把Flutter接收到原生的参数,再传回原生,当然也可以是任意Flutter端处理过任意数据
                  nativeChannel.invokeMethod('jumpToNative', result);
                } ,
              )

onActivityResult的实现方式

Flutter端发送数据

RaisedButton(
    child: Text('返回上一页'),
    onPressed: () {
      // 返回给上一页的数据
      Map<String, dynamic> result = {'message': '我从Flutter页面回来了'};
      nativeChannel.invokeMethod('goBackWithResult', result);
    }),

安卓端接收并处理

//通过methodCall.argument()获取Flutter的参数,然后自行处理
nativeChannel.setMethodCallHandler(new MethodChannel.MethodCallHandler() {
    @Override
    public void onMethodCall(MethodCall methodCall, MethodChannel.Result result) {
        switch (methodCall.method) {
            case "goBackWithResult":
                // 返回上一页,携带数据
                Intent backIntent = new Intent();
                backIntent.putExtra("message", (String) methodCall.argument("message"));
                setResult(RESULT_OK, backIntent);
                finish();
                break;
        }
    }
});

总结:Flutter端与原生端交互的方式:

  1. MethodChannel:用于传递方法调用(method invocation),Flutter和平台端进行直接方法调用时候可以使用。
  2. BasicMessageChannel:用于传递字符串和半结构化的信息,Flutter和平台端进行消息数据交换时候可以使用。
  3. EventChannel:用于数据流(event streams)的通信,Flutter和平台端进行事件监听、取消等可以使用。
    当前只用了其中一种最常用的,后面会继续讲其他方式,其实我们仔细思考一下,这种C/S架构是不是两两通信最朴素的方法
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Alex_ChuTT

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值