码个蛋(codeegg)第 743 次推文
Flutter 说到底只是一个 UI 框架,很多功能都需要通过原生的 Api 来实现,那么就会涉及到 Flutter 和 Native 的交互,因为本人不懂 iOS 开发,所以只能讲下 Flutter 同 Android 的交互。
Android项目配置Flutter依赖
既然是互相交互,那么需要准备一个 Android 项目。接着就需要创建 flutter module,让 Android 项目依赖,创建的方法可以参考官网 Flutter Wiki,虽然是官网提供的方法,但是完全按照这个步骤来,还是会有坑的,这边就慢慢一步步解决坑。
如果你用的是 Android Studio 进行开发的话,直接打开底部的 Terminal,直接创建 flutter module 依赖
flutter create -t module flutter_native_contact
至于 module 名可以随意填写,module 创建完后结构大概是这样的
![8f706ccba21acb12b442981769bb1316.png](https://i-blog.csdnimg.cn/blog_migrate/24d0c69d7eea76b40a3dae519b7c1b2d.jpeg)
flutter module.png
接着切换到 module 下的 .android 文件夹,接着有坑来了,官网提供的方法是 ./gradlew flutter:assembleDebug
可能会提示命令不存在,那么直接通过gradlew flutter:assembleDebug
来运行,等它自动跑完后,打开根目录下的settings.gradle
文件,加入官网提供的 gradle 代码
setBinding(new Binding([gradle: this])) // new
evaluate(new File( // new
settingsDir.parentFile, // new
'flutter_native_contact/.android/include_flutter.groovy' // new
))// new
你以为这里没坑,真是图样图森破,没坑是不可能的,编译器大爷可能会给你甩这么个错误
![de41322058acfd12d35c04016dd10b86.png](https://i-blog.csdnimg.cn/blog_migrate/5eb2495680ad46ac3eff0e639df7c7ec.jpeg)
很明显可以看出是找不到我们的文件,所以把文件名路径给补全
evaluate(new File( // new
settingsDir.parentFile, // new
'FlutterNativeContactDemo/flutter_native_contact/.android/include_flutter.groovy' // 这里补全路径
))
接着打开原有项目下,原有项目下,原有项目下的 app 中的 build.gradle
文件,在 android 下加上如下代码
compileOptions {
sourceCompatibility 1.8
targetCompatibility 1.8
}
这个必须要加,不要问为什么,我也不知道为什么,最后在项目下添加 flutter module 的依赖就完成了。这个过程告诉我们一个什么道理呢?*不要以为官网的都对,官网讲的也不是完全可信的,时不时给你来个坑就能卡你老半天。
原生界面加载Flutter页面
那么如何在原生界面显示 Flutter 界面呢,这个就需要通过 FlutterView 来实现了,Flutter 这个类提供了 createView
和createFragment
两个方法,分别用于返回 FlutterView 和 FlutterFragment 实例,FlutterFragment 的实现原理也是通过 FlutterView 来实现的,可以简单看下 FlutterFragment 的源码
/**
* A {@link Fragment} managing a {@link FlutterView}.
*
*
Warning: This file is auto-generated by Flutter tooling.
* DO NOT EDIT.
*/
public class FlutterFragment extends Fragment {
public static final String ARG_ROUTE = "route";
private String mRoute = "/";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 获取传入的路由值,默认为 '/'
if (getArguments != ) {
mRoute = getArguments.getString(ARG_ROUTE);
}
}
@Override
public FlutterView onCreateView(@Non LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
// 最后还是挺过 createView 方法来生成页面,只不过直接放在 fragment,
// 放在 fragment 会比直接 使用 FlutterView 更方便管理,例如实现 ViewPager 等
return Flut