Flutter与原生交互
Posted 一个小码农的成长史
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flutter与原生交互相关的知识,希望对你有一定的参考价值。
当我们在已有的项目改造成一个新的Flutter项目的话,要重写构架不仅花的时间很长,并且Flutter现在还是一个测试的版本,存在或多或少的bug。但是如果我们只是在项目的某个模块进行改造,或者是加入一个新模块时间比较赶,这个时候就可以使用Flutter与原生混合是编程。这样就可以在不影响现有的项目的基础上,优化自己的项目啦。
一.创建Flutter Module模式
我们使用命令来创建一个新的插件具体代码如下
D:\workSpace>flutter create -t module my_flutter
setBinding(new Binding([gradle: this]))
evaluate(new File(
settingsDir.parentFile,
'my_flutter/.android/include_flutter.groovy'
))
如上所示,我创建的项目名称是my_flutter,并且在原生项目的同级目录下,所以才是如上配置。此时就会自动生成一个名为flutter的Module。
3.在app.gradle引用flutter Module如下所示
implementation project(':flutter')
此时就配置完成了原生和Flutter Module。
二.Flutter 与原生交互
1.原生代码的实现
首先我们在原生页面中创建一个activity,基础FlutterActivity,如下,然后再Activity中配置自己的FlutterView。具体实现代码如下:
public class FMyInfoActivity extends FlutterFragmentActivity {
private MethodChannel mMethodChannel;
private final static String CHANNEL = "samples.flutter.io/test";
private FrameLayout fl;
private FlutterView flutterView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.f_me_myinfo_activity);
fl = findViewById(R.id.root);
flutterView = Flutter.createView(this, getLifecycle(), "myInfo");
fl.addView(flutterView);
FlutterView.FirstFrameListener[] listeners = new FlutterView.FirstFrameListener[1];
listeners[0] = () -> fl.setVisibility(View.VISIBLE);
flutterView.addFirstFrameListener(listeners[0]);
mMethodChannel = new MethodChannel(flutterView, CHANNEL);
}
}
为了防止启动Flutteractivity出现黑屏,我们使用了监听了启动的第一帧,显示的则是布局的颜色。
我们创建了一个FlutterView, 第三个参数为route路径,当原生页面启动此页面时,进入Flutter的main函数启动app,此时传入根据不同的route,进入不同的flutter页面。
添加的MethodChannel起了与Flutter交互的桥梁的作用。
2.Flutter代码的实现
void main() => runApp(MyApp(window.defaultRouteName));
class MyApp extends StatelessWidget {
final String route;
MyApp(this.route);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "测试项目",
home: _widgetForRoute(route),
);
}
Widget _widgetForRoute(String route) {
switch (route) {
case "myinfo":
return UserPageView();
default:
return Center(
child:
Text('Unknown route: $route', textDirection: TextDirection.ltr),
);
}
}
}
在main.dart中实现如下代码。
三.使用MethodChannel与原生交互
methodChannel作为两边交互的桥梁。首先原生如何向Flutter传值呢,原生和Flutter都创建一个同一个名称的Channel,打通双方的传值通道,当Flutter需要原生的一个值时,此时Flutter向原生发送一个通道请求如下
MethodChannel platform = const MethodChannel("samples.flutter.io/test");
//获取原生过来的用户信息
_getUserInfo() {
platform.invokeMethod("getUserInfo").then((result) {
return json.decode(result);
}).then((jsonInfo) {
setState(() {
_userInfo = jsonInfo;
});
}).catchError((onError) {
print("catchError\r\n" + onError.toString());
});
}
mMethodChannel.setMethodCallHandler((methodCall, result) -> {
if (methodCall.method.equals("getUserInfo")) {
String data = SPUtils.getString(AppConstans.USER_INFO, "");
result.success(data);
} else {
result.notImplemented();
}
});
如上所示如果双方的methodChannel名称一致,此时原生返回一个result给Flutter,Flutter获取到参数,并改变参数的值,这个流程则是原生给Flutter传值。
2.原生如何获取Flutter的值呢?首先原生这边发送一个通道请求给Flutter如下所示:
mMethodChannel.invokeMethod("refreshInfo","");
第一个参数为请求的名称,第二个参数则为传递的参数,可以为空,此时Flutter获取到原生的请求,做出相对的回应,如下所示
platform.setMethodCallHandler((methodCall){
if(methodCall.method=="refreshInfo"){
_getUserInfo()
}
});
此时就完成了原生对Flutter的调用了,如果要传递参数的话,只需在双方的
invokeMethod()方法的第二个参数传入你要传递的参数就好啦。
以上就是Flutter与原生混合开发的全部内容啦。
以上是关于Flutter与原生交互的主要内容,如果未能解决你的问题,请参考以下文章