原生项目集成Flutter
- 创建Flutter module
- 添加Flutter module依赖
- 在Java/Object-c中调用Flutter module
- 编写Dart代码
1.创建FlutterModule
首先在你的Native项目的上一级目录,运行如下代码
flutter create -t module flutter_module
这样,就会创建一个flutter模块
我们进入flutter_module
,可以发现包含.android
和.ios
,这两个文件夹是隐藏文件,也是这个flutter_module
宿主工程
-
.android
- flutter_module的Android宿主工程 -
.ios
- flutter_module的IOS宿主工程 - lib - flutter_module的Dart部分的代码
- pubspec.yaml - flutter_module的项目依赖配置文件
因为宿主工程的存在,我们这个flutter_module在不加额外的配置的情况下是可以独立运行的。通过安装了Flutter与Dart插件的Android Studio打开这个flutter_module项目,通过运行按钮是可以直接运行它的
2.添加Flutter module依赖
在我们的原生Android项目的settings.gradle中添加如下代码
这一步是引用flutter工程,添加之后Binding会报红,这个地方不管他
setBinding(new Binding([gradle:this]))
evaluate(new File(settingsDir.parentFile,'flutter_module/.android/include_flutter.groovy'))
然后在app的build.gradle中,添加
dependencies {
//...
implementation project(":flutter")
}
Android项目minSdkVersion最低需为16
Android项目需配置使用1.8进行编译 (sourceCompatibility和targetCompatibility)
3.在Java中调用Flutter module
使用Flutter.createView API的方式
View flutterView = Flutter.createView(MainActivity.this, getLifecycle(), "route1");
FrameLayout.LayoutParams layout = new FrameLayout.LayoutParams(600, 800);
layout.leftMargin = 100;
layout.rightMargin = 200;
addContentView(flutterView, layout);
使用FlutterFragment的方式
FragmentTransaction tx = getSupportFragmentManager().beginTransaction();
tx.replace(R.id.layout_container, Flutter.createFragment("route1"));
tx.commit();
上面我们使用字符串"route1"来告诉Dart代码在Flutter视图中显示哪个小部件。
Flutter模块项目的lib/main.dart
文件需要通过window.defaultRouteName
来获取Native指定要显示的路由名,以确定要创建哪个窗口小部件并传递给runApp;
4.编写Dart代码
import 'package:flutter/material.dart';
import 'dart:ui';
void main() => runApp(MyApp(initParams : window.defaultRouteName));
class MyApp extends StatelessWidget {
final String initParams;
const MyApp({Key key,this.initParams}):super(key:key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page',initParams:initParams),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title,this.initParams}) : super(key: key);
final String title;
final String initParams;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'initParams:${widget.initParams}',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.display1,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
运行Android项目,点击FLUTTER FRAGMENT
按钮,可以看到
无论是使用
Flutter.createView
的方式还是通过Flutter.createFragment
的方式,都允许我们在加载Flutter module
时传递一个String类型的initialRoute参数,该参数是用作路由名的,但也可以传递相传的其他的参数,比如json类型的数据。
混合开发进行热重启/热加载
我们在开发纯Flutter项目的时候,带有热重启/热加载的功能,但在混合开发的集成了Flutter的Android项目中,需要进行额外的操作。
- 打开一个模拟器,或链接一个设备到电脑上
- 关闭我们的APP,然后运行Flutter attach
cd flutter_module
flutter attach
如果你连接了多个设备,
flutter attach
会提示你选择一个设备,需要使用flutter attach -d 来指定一个设备
然后运行Android项目,并执行了Flutter相关的功能,会在控制台打印如下的信息
如果是热加载,按r
如果是热重启,按R
如果想请求帮助,按h
如果想退出,按q
接着,就可以再Flutter工程中修改代码了, 修改完毕后,按r就执行了热加载
调试Dart代码
混合开发的模式下,如何调试代码
- 关闭App (很关键)
- 点击AS的
Flutter Attach
按钮 (首先需要安装Flutter和Dart插件) - 启动App
接下来就可以像调试普通Flutter项目一样来调试混合开发模式下的Dart代码了
运行Android工程时一定要再Android模式下的Android Studio中运行,因为Flutter模式下的Android Studio运行的是
.android
中的Android工程