一个App的某个页面是Flutter开发的,或者某个模块等。即为Flutter与Native的混合开发。
分为:Flutter与Android混合开发、Flutter与ios混合开发。
混合开发的场景:作为独立页面进行加入、作为页面的一部分嵌入。
Flutter集成步骤:
1.创建Flutter module
2.添加Flutter module依赖
3.在Java/object-c种调用Flutter module
4.调用Dart代码
5.运行项目
1.创建Flutter module:
假如Native项目是: xxx/flutter_test/Native项目
cd xxx/flutter_test/
flutter create -t module flutter_module
也可以直接使用Android Studio的图形化界面进行创建Flutter module.
上面的代码会切换到Android/ios项目的上一级目录,并创建一个flutter模块:
# flutter_module/:
.android
.gitgnore
.idea
.ios
.metadata
.packages
build
flutter_module_android.iml
flutter_module.iml
lib
pubspec.lock
pubspec.yaml
README.md
test
上面是flutter_module的文件结构,包含.android和.ios,这2个文件夹是隐藏文件,也是flutter_module的宿主工程。
因为宿主工程的存在,flutter_module在不加额外的配置的情况下是可以独立运行的,通过安装了Flutter与Dart插件的AndroidStudio打开这个flutter_module项目,通过运行按钮就可以直接运行它。
2.添加Flutter module依赖
AndroidStudio打开.android,将视图切换到Android后,在下方找到settings.gradle文件:
//MyApp/settings.gradle
include ':app'
setBinding(new Binding([gradle: this]))
evaluate(new File(
settingsDir.parentFile,
'flutter_module/.android/include_flutter.groovy'//new
))
然后在build.gradle(Module: app)文件中添加依赖:
implementation project(':flutter')
然后Build 工程。
3.在Java/object-c种调用Flutter module
在Java中调用Flutter模块的2种方式:
3.1 使用Flutter.createView
3.2 使用FlutterFragment的方式
//MainActivity.java
fab.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View view){
View flutterView = Flutter.createView(
MainActivity.this,
getLifecycle(),
'route1'
);
FrameLayout.LayoutParams layout = new FrameLayout.LayoutParams(600,800);
layout.leftMargin = 100;
layout.topMargin = 200;
addContentView(flutterview,layout);
}
});
创建一个FlutterFragment来自己处理声明周期。
//MainActivity.java
fab.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View view){
FragmentTransaction tx = getSupportFragmentManager().beginTransaction();
tx.replace(R.id.someContainer,Flutter.createFragment("route1"));
tx.commit();
}
});
//activity_main.xml
....
....
其中的R.id.someContainer是xml中配置的Fragment的占位符。使用字符串“route1”来告诉Dart代码在Flutter视图中显示哪个小部件,Flutter模块项目的lib/main.dart文件需要通过window.defaultRouteName来获取Native指定需要显示的路由名,以确定要创建哪个窗口小部件并传"递给runApp:
注意:
Flutter集成的时候,要求原生Android的minSdkVersion: 16+
原生项目编译的时候需要设置Java 8:
compileOptions{
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
上述3中,有个Flutter.createFragment("route1"));,那么如何取route1字符串呢?
在Dart中,
....
import 'dart:ui';//导入window对象
void main() => runApp(MyApp(initParams: window.defaultRouteName,));
class MyApp extends StatelessWidget{
final String initParams;
const MyApp({Key key,this.initParams}) : super(key: key);
....
Widget build(){
...
home: MyHomePage(initParams: initParams);
}
}
class MyHomePage extends StatefulWidget{
final String initParams;
.....
}
class _MyHomePageState extends State{
//展示
...
Text('initParams: $(widget.initParams)');
...
}
上面4中,无论是通过Flutter.createView还是Flutter.createFragment的方式,都允许我们在加载Flutter module的时候传递一个String类型的initialRoute参数,从参数的名字它是用做路由名的,但是既然Flutter开了一个口子,那就可以利用它做其他事情,传递我们像传递的参数。比如传递json字符串。