当前位置:   article > 正文

android flutter 混合开发,Flutter(六)Android与Flutter混合开发(Hybird)

flutter android:gravity

4bf618c32506

因为笔者本身主要从事是Android开发,所以很多角度都是作为一个Android开发者学习Flutter的角度出发,IOS或者H5的开发同学可以选择性阅读

目录

4bf618c32506

前言

如果我们目前的项目是Android的,但是接下来我们希望部分页面可以使用Flutter进行开发,甚至我们希望在Native页面中嵌入FlutterUI组件,那么我们该如何实现呢?

创建Flutter Module

假设你现在Android项目的目录的结构是这样的

xxx/flutter_hybrid/FlutterHybridAndroid

这时候如果你想创建一个Flutter模块,使得Android模块和Flutter模块之间可以进行交互,我们可以通过Android Studio新建一个Flutter Module,具体过程是:File —> New —> New Module ,之后选择Flutter Module,指定Project Location的路径为

xxx/flutter_hybrid

也就是说,最终你的项目结构会是这样的

- flutter_hybrid

- flutter_module

- FlutterHybridAndroid

接下来在Android Module的build.gradle文件中添加flutter依赖

//FlutterHybridAndroid/app/build.gradle

...

dependencies {

implementation project(':flutter')

...

}

Android启动Flutter页面的两种方式

先创建一个Flutter页面

这里比较重要的是window.defaultRouteName这个字段,这个字段可以接收从Native传递过来的参数(下文我们会介绍原生传递参数的方法),也就是说通过这个字段我们就可以进行Flutter页面的路由的分发

import 'dart:ui';

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {

@override

Widget build(BuildContext context) {

return MaterialApp(

title: 'FlutterHybird',

theme: ThemeData(

primarySwatch: Colors.blue,

),

//window.defaultRouteName可以接收从Native传过来的参数

home: _widgetForRoute(window.defaultRouteName),

);

}

}

Widget _widgetForRoute(String route) {

switch (route) {

case 'route1':

return Center(

child: Text("route1"),

);

case 'route2':

return Center(

child: Text("route2"),

);

default:

return Center(

child: Text('Unknown route: $route', textDirection: TextDirection.ltr),

);

}

}

直接启动一个FlutterActivity

我们可以直接在Android的MainActivity中启动一个FlutterActivity,这里的initialRoute方法中传递的参数就对应Flutter层的window.defaultRouteName

findViewById(R.id.jump).setOnClickListener(v -> {

startActivity(FlutterActivity.withNewEngine()

.initialRoute("route2")

.build(MainActivity.this));

});

注意:需要在AndroidManifest.xml注册FlutterActivity

android:name="io.flutter.embedding.android.FlutterActivity"

android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"

android:hardwareAccelerated="true"

android:windowSoftInputMode="adjustResize" />

启动复写后的FlutterActivity(推荐)

自己创建一个FlutterAppActivity继承自FlutterActivity

public class FlutterAppActivity extends FlutterActivity {

public final static String INIT_PARAMS = "initParams";

private String initParams;

public static void start(Context context, String initParams) {

Intent intent = new Intent(context, FlutterAppActivity.class);

intent.putExtra(INIT_PARAMS, initParams);

context.startActivity(intent);

}

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

initParams = getIntent().getStringExtra(INIT_PARAMS);

}

/**

* 重载该方法来传递初始化参数

*

* @return

*/

@NonNull

@Override

public String getInitialRoute() {

return initParams == null ? super.getInitialRoute() : initParams;

}

}

在MainActivity中启动FlutterAppActivity(另外别忘了在AndroidManifest.xml中注册FlutterAppActivity)

findViewById(R.id.jump).setOnClickListener(v -> {

FlutterAppActivity.start(MainActivity.this,"route2");

});

两种启动方式的区别

如果单纯只是想打开一个Flutter页面,两种方式实际上基本没有太大区别,第一种方式也许还会更简单一点。但是,在Flutter开发中,我们往往还需要开发一些Native插件供Flutter调用,如果使用复写FlutterActivity的方式更有利于我们在FlutterActivity中注册我们的Native插件,所以实际开发中一般推荐使用第二种方式

扩展思考

initialRoute从名称上看起来是Flutter提供给我们进行Native与Flutter交互的路由跳转的,但是实际上他就是一个字符串,我们不仅仅可以传递一个路由名称,有时候我们也可以通过这个参数传递一串JSON数据,然后在Flutter端进行解析,这样我们就可以通过这个参数做更多的事情

在Android原生页面中嵌入FlutterUI组件

activity_main.xml

FrameLayout用于承载Flutter组件

xmlns:app="http://schemas.android.com/apk/res-auto"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical"

tools:context=".MainActivity">

android:layout_width="match_parent"

android:layout_height="0dp"

android:layout_weight="1"

android:background="@color/colorAccent"

android:gravity="center"

android:text="Hello World!" />

android:id="@+id/container"

android:layout_width="wrap_content"

android:layout_height="0dp"

android:layout_weight="1">

MainActivity.java

使用FragmentManager将FlutterFragment添加到FrameLayout容器中

FlutterFragment fragment = FlutterFragment.withNewEngine().initialRoute("route1").build();

getSupportFragmentManager()

.beginTransaction()

.replace(R.id.container, fragment)

.commit();

运行结果

上半部分是原生的TextView,下半部分是Flutter的Text组件

4bf618c32506

总结

本节主要介绍了Native和Flutter之间的页面跳转,以及同一个页面中Native与Flutter组件的组合。接下来会介绍如何编写Android插件与Flutter进行数据交互

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/425636
推荐阅读
相关标签
  

闽ICP备14008679号