前置:参照【Flutter路由参数1 - 路由管理】中配置命名路由routes、onGenerateRoute。
1 参数分析
分析Flutter路由传递参数和浏览器参数传递的区别:
| 访问页面方式 | RouteSettings对象区别 |
|---|---|
浏览器访问:http://localhost:54227/router?page-title=test-router
|
RouteSettings("/router", {page-title: test-router}) |
Navigator路由:Navigator.pushNamed(context, TestRouterPage.routeName, arguments: {"page-title": "test-router"});
|
RouteSettings("/router?page-title=test-router", null) |
查看RouteSettings构造方法以看出,使用浏览器get请求时,会将url和参数一起拼接到name属性中。
const RouteSettings({
this.name,
this.arguments,
});
2 处理思路
对于RouteSettings的name属性,如果其包含参数,则拆分后存储到arguments中。
代码处理如下:
class TestRouter {
static Map<String, Function> routes = {
TestRouterPage.routeName: (context) => const TestRouterPage(),
};
var onGenerateRoute = (RouteSettings settings) {
String? name = settings.name;
if (name != null) {
List<String> nameList = name.split("?");
name = nameList[0];
final Function? pageBuilder = routes[name];
if (pageBuilder != null) {
// settings.arguments不为空,直接路由
if (settings.arguments != null) {
return MaterialPageRoute(builder: (context) => pageBuilder(context), settings: settings);
}
// settings.arguments为空,尝试从name中获取url参数
return MaterialPageRoute(builder: (context) => pageBuilder(context), settings: handleArguments(nameList, settings) ?? settings);
}
}
return MaterialPageRoute(builder: (context) => WebPage(const Page404()));
};
/// Url中参数组装覆盖RouteSettings的参数arguments
static RouteSettings? handleArguments(List<String> nameList, RouteSettings settings) {
if (nameList.length <= 1) return null;
Map paramMap = {};
nameList[1].split("&").forEach((param) {
List paramList = param.split("=");
paramMap[paramList[0]] = paramList[1];
});
return settings.copyWith(arguments: paramMap);
}
}