转载Flutter集成到Android项目三部曲 - ezbuy_Metal团队 - 掘金专栏
3. 嵌入View并传递参数
上面虽然能够跳转指定页面了,但是很显然,有一个很大的问题:不能传递参数。
这是Flutter的静态路由的一个很大的弊端,虽然通过动态路由可以传递参数和接收返回值,但是动态路由没法给原生调用。
Navigator.of(context)
.push(new MaterialPageRoute(builder: (context) {
return new NextPage(params);
})).then((String value) {
setState(() {
params = value;
});
});
复制代码
有一个Flutter的路由库:Fluro,可以实现静态路由传参,例如这样:
传参
var bodyJson = '{"user":1281,"pass":3041}';
router.navigateTo(context, '/home/$bodyJson');
复制代码
接收
Router router = new Router();
void main() {
router.define('/home/:data', handler: new Handler(
handlerFunc: (BuildContext context, Map params) {
return new FluroHomePage(params['data'][0]);
}));
runApp(MyApp());
}
复制代码
但是,这种方式在Flutter内部还行,却无法给原生调用,在原生里面通过Flutter.createView的时候,是没法使用Fluro的,只能是默认的路由。
调研了很多方案,最后,没有办法了,只好采用最笨的方法:通过MethodChannel来传递参数。
这里需要注意的是MethodChannel的调用,应该FlutterView已经创建完成,所以需要通过flutterView.post(new Runnable())来执行了,直接执行是不会传参给Flutter的。
原生传参给Flutter
原生调用
MethodChannel channel = new MethodChannel(flutterView, CHANNEL);
channel.invokeMethod("invokeFlutterMethod", "hello,flutter", new MethodChannel.Result() {
@Override
public void success(@Nullable Object o) {
Log.i("flutter","1.原生调用invokeFlutterMethod-success:"+o.toString());
}
@Override
public void error(String s, @Nullable String s1, @Nullable Object o) {
Log.i("flutter","1.原生调用invokeFlutterMethod-error");
}
@Override
public void notImplemented() {
Log.i("flutter","1.原生调用invokeFlutterMethod-notImplemented");
}
});
复制代码
Flutter执行
platform.setMethodCallHandler((handler) {
Future future=Future((){
switch (handler.method) {
case "invokeFlutterMethod":
String args = handler.arguments;
print("2.Flutter执行invokeFlutterMethod:${args}");
return "this is flutter result";
}
});
return future;
});
复制代码
Flutter传参给原生
Flutter调用
print("3.Flutter调用invokeNativeMethod");
int result =
await platform.invokeMethod("invokeNativeMethod", "hello,native");
print("5.收到原生执行结果:${result}");
复制代码
原生执行
channel.setMethodCallHandler(new MethodChannel.MethodCallHandler() {
@Override
public void onMethodCall(MethodCall call, MethodChannel.Result result) {
switch (call.method) {
case "invokeNativeMethod":
String args = (String) call.arguments;
Log.i("flutter","4.原生执行invokeNativeMethod:"+args);
result.success(200);
break;
default:
}
}
});
复制代码
最后贴一下这个传参页面的完整代码吧,主要就是跑了一下:
- 原生调用invokeFlutterMethod
- Flutter执行invokeFlutterMethod
- Flutter调用invokeNativeMethod
- 原生执行invokeNativeMethod
Android:
public class ChannelFlutterActivity extends AppCompatActivity {
private static final String CHANNEL = "com.ezbuy.flutter";
FlutterView flutterView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_channel);
FrameLayout frFlutter = findViewById(R.id.fr_flutter);
flutterView = getFlutterView("channelPage");
frFlutter.addView(flutterView);
flutterView.post(new Runnable() {
@Override
public void run() {
initMethodChannel(flutterView);
}
});
}
public FlutterView initMethodChannel(FlutterView flutterView) {
MethodChannel channel = new MethodChannel(flutterView, CHANNEL);
//1.原生调用Flutter方法
channel.invokeMethod("invokeFlutterMethod", "hello,flutter", new MethodChannel.Result() {
@Override
public void success(@Nullable Object o) {
Log.i("flutter","1.原生调用invokeFlutterMethod-success:"+o.toString());
}
@Override
public void error(String s, @Nullable String s1, @Nullable Object o) {
Log.i("flutter","1.原生调用invokeFlutterMethod-error");
}
@Override
public void notImplemented() {
Log.i("flutter","1.原生调用invokeFlutterMethod-notImplemented");
}
});
Log.i("flutter","1.原生调用invokeFlutterMethod");
//4.Flutter调用原生方法的监听
channel.setMethodCallHandler(new MethodChannel.MethodCallHandler() {
@Override
public void onMethodCall(MethodCall call, MethodChannel.Result result) {
switch (call.method) {
case "invokeNativeMethod":
String args = (String) call.arguments;
Log.i("flutter","4.原生执行invokeNativeMethod:"+args);
result.success(200);
break;
default:
}
}
});
return flutterView;
}
public FlutterView getFlutterView(String initialRoute) {
return Flutter.createView(
this,
getLifecycle(),
initialRoute
);
}
}
复制代码
Flutter
class ChannelPage extends StatefulWidget {
ChannelPage();
@override
_ChannelPageState createState() => _ChannelPageState();
}
class _ChannelPageState extends State {
static const platform = const MethodChannel('com.ezbuy.flutter');
String data;
@override
void initState() {
super.initState();
data ="默认data";
initChannel();
}
@override
Widget build(BuildContext context) {
//必须用Scaffold包裹
return Scaffold(body: new Center(child: new Text(data)));
}
void initChannel() {
platform.setMethodCallHandler((handler) {
Future future=Future((){
switch (handler.method) {
case "invokeFlutterMethod":
String args = handler.arguments;
print("2.Flutter执行invokeFlutterMethod:${args}");
setState(() {
data = "2.Flutter执行invokeFlutterMethod:${args}";
});
invokeNativeMethod();
return "this is flutter result";
}
});
return future;
});
}
void invokeNativeMethod() async {
print("3.Flutter调用invokeNativeMethod");
int result =
await platform.invokeMethod("invokeNativeMethod", "hello,native");
print("5.收到原生执行结果:${result}");
}
}
作者:ezbuy_Metal团队
链接:https://juejin.im/post/5c6f77d7f265da2dbb122fe1
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。