需求
我们在开发应用中,经常会出现一个界面跳转到另外一个界面并带有参数传递,在Android中大家都知道使用Intent传递参数,在第二个Activity中onCreate中可以获取到这个参数。
实现
那么在Flutter中,我们经常会使用路由跳转到另外一个界面,那么如果这个时候需要传参。 代码如下:
/// 路由跳转并带参数
Navigator.pushNamed(
context,
RouteConst.routeNext,
arguments: (TestArguments("一笑轮回", "江苏省徐州市")),
);
/// 测试数据模型
class TestArguments {
String? name;
String? address;
TestArguments(this.name, this.address);
}
没错,直接赋值arguments字段就可以了,那么我们如何获取呢?
在第二个页面中
class TwoPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
// 从路由设置中获取传递的参数
var arguments = ModalRoute.of(context)?.settings.arguments;
// 其他部分的代码...
}
}
我们需要通过 ModalRoute.of(context)?.settings.arguments获取数据,那么我们直接在 initState方法中直接通过 ModalRoute.of(context)?.settings.arguments获取,会报错
这里出错原因,可以通过错误并查看源码可知,这里部讲述。
我们有的时候需要在initState方法中获取数据并处理一些事情,我们应该怎么做呢?
下面提供一个小技巧。
- 路由定义
class RouteConst {
static const routeNext = "/route_next";
}
class RoutePathConst {
static var routePaths = <String, Widget Function(BuildContext context)>{
RouteConst.routeNext: (context) => ArgumentsNextPage(),
};
}
- 跳转代码
Navigator.pushNamed(
context,
RouteConst.routeNext,
arguments: (TestArguments("一笑轮回", "江苏省徐州市")),
);
/// 测试数据模型
class TestArguments {
String? name;
String? address;
TestArguments(this.name, this.address);
}
- 定义ArgumentsMixin
/// Arguments参数数据
mixin ArgumentsMixin {
late final Object? arguments;
}
/// 路由拼接的参数数据
mixin RouteQueryMixin {
final Map<String, String> routeParams = HashMap();
}
- 重写onGenerateRoute
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
...
onGenerateRoute: (settings) {
var uri = Uri.parse(settings.name ?? "");
var route = uri.path;
var params = uri.queryParameters;
if (!RoutePathConst.routePaths.containsKey(route)) {
return null;
}
return MaterialPageRoute(
builder: (context) {
var widgetBuilder = RoutePathConst.routePaths[route];
var widget = widgetBuilder!(context);
if (widget is RouteQueryMixin) {
(widget as RouteQueryMixin).routeParams.addAll(params);
}
if (widget is ArgumentsMixin) {
(widget as ArgumentsMixin).arguments = settings.arguments;
}
return widget;
},
settings: settings,
);
},
);
}
}
- 创建ArgumentsNextPage
///第二页
class ArgumentsNextPage extends StatefulWidget
with ArgumentsMixin, RouteQueryMixin {
ArgumentsNextPage({super.key});
@override
State<ArgumentsNextPage> createState() => _ArgumentsNextPageState();
}
class _ArgumentsNextPageState extends State<ArgumentsNextPage> {
/// 传参数据文本
String get result {
// Arguments传参数据
TestArguments? arguments;
if (widget.arguments != null && widget.arguments is TestArguments) {
arguments = widget.arguments as TestArguments;
}
// 路由拼接的数据
var params = widget.routeParams;
// 拼接结果数据
return "arguments:name=${arguments?.name ?? ""} address=${arguments?.address ?? ""} \nrouteParams=$params";
}
@override
void initState() {
super.initState();
print("result=$result}");
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: XYAppBar(
title: "第二页",
onBack: () {
Navigator.pop(context);
},
),
body: Center(
child: Text(result),
),
);
}
}
这样就OK了,好像没讲啥,直接看代码吧。