2.7 KiB
2.7 KiB
【Demo】详情页:参数接收的两种通道
源文件:
lib/pages/demo/detail_page.dart| 分类:路由 一句话:构造参数与 ModalRoute arguments 双通道 —— 谁来了用谁,缺谁兜底。
一、这个 Demo 解决什么问题
同一个详情页,可能被两种方式打开:
- 方式 1:
push构造传参(DetailPage(name: '张三', age: 18)); - 方式 3:
pushNamed命名路由 + arguments({'name': '李四', 'age': 25})。
页面要同时兼容两种入口:优先用 arguments 里的值,没有就用构造参数兜底。
二、怎么运行 / 演示内容
runApp(const RouterApp());
首页分别用方式 1 / 方式 3 跳进来,观察两种取参路径的效果。
三、核心知识点(新手向)
1. 构造参数(类型安全)
class DetailPage extends StatelessWidget {
const DetailPage({super.key, this.name = '默认', this.age = 0});
final String name;
final int age;
...
}
- 带默认值 → 不传参也能打开,不会崩;
- 类型安全:传错类型编译期报错。
2. 命名路由 arguments(运行期 Map)
final args = ModalRoute.of(context)?.settings.arguments;
final argMap = args is Map<String, dynamic> ? args : null;
ModalRoute.of(context)拿到当前路由 →.settings.arguments取出 pushNamed 传的参数;- arguments 是 dynamic,必须判空强转:
- 不是 Map(或没传)→
argMap为 null; argMap?['name']取不到时用?? name回退构造参数。
- 不是 Map(或没传)→
3. 双通道合并取值(本页精髓)
Text('姓名:${argMap?['name'] ?? name}'),
Text('年龄:${argMap?['age'] ?? age}'),
"arguments 优先,构造参数兜底"——两种入口都兼容,缺参不崩。
四、关键代码剖析
// 手动 pop(AppBar 的返回箭头也是 pop,效果一样)
OutlinedButton(
onPressed: () => Navigator.pop(context),
child: const Text('返回上一页'),
)
五、踩坑记录
arguments是 dynamic,直接用会崩(args['name']对非 Map 类型运行期报错)——先is Map判断;ModalRoute.of(context)?.settings.arguments有?,路由可能为 null;- 构造参数给默认值,保证"零参数也能打开页面"(debug 直达页面时很有用);
- 命名路由注册在 router_demo.md 的 routes 表里。
六、扩展思考
- 选择器页 pop 带值见 picker_page.md;
- 参数多了建议封装成强类型对象(
class DetailArgs),避免 Map 满天飞; - 真实项目(go_router)用
GoRoute的arguments或extra传对象,原理一致。