Flutter 从入门到精通(水)

187 阅读2分钟

第5章:路由与导航系统

在 Flutter 中,每一个页面都是一个 Widget。路由(Route) 就是这些页面的跳转逻辑,导航(Navigator) 则是用于管理页面栈的工具。


一、路由的基本概念

Flutter 的页面跳转采用栈结构:

  • 入栈(push)表示页面跳转
  • 出栈(pop)表示返回上一页

示例结构:

HomePage → DetailPage → SettingPage

二、页面跳转方式

1. 非命名路由(直接传 Widget)

Navigator.push(
  context,
  MaterialPageRoute(builder: (context) => DetailPage()),
);

返回上一页:

Navigator.pop(context);

2. 命名路由(推荐用于大型项目)

MaterialApp 中统一注册页面:

MaterialApp(
  initialRoute: '/',
  routes: {
    '/': (context) => HomePage(),
    '/detail': (context) => DetailPage(),
  },
)

跳转:

Navigator.pushNamed(context, '/detail');

3. 页面传参

非命名路由传参:
Navigator.push(
  context,
  MaterialPageRoute(
    builder: (context) => DetailPage(id: 123),
  ),
);
命名路由传参(推荐配合 onGenerateRoute):
Navigator.pushNamed(context, '/detail', arguments: 123);

接收参数:

final id = ModalRoute.of(context)?.settings.arguments as int;

三、动态路由注册(onGenerateRoute)

适合复杂页面动态构建 + 参数传递:

MaterialApp(
  onGenerateRoute: (settings) {
    if (settings.name == '/detail') {
      final id = settings.arguments as int;
      return MaterialPageRoute(
        builder: (context) => DetailPage(id: id),
      );
    }
    return null;
  },
)

四、返回值的传递

跳转时接收页面返回值:

final result = await Navigator.push(
  context,
  MaterialPageRoute(builder: (_) => InputPage()),
);

print("用户输入:$result");

在新页面中返回值:

Navigator.pop(context, "Hello!");

五、清除历史记录跳转(如登录后跳转首页)

Navigator.pushAndRemoveUntil(
  context,
  MaterialPageRoute(builder: (_) => HomePage()),
  (route) => false,
);

此写法会清空导航栈,适合如登录→主页、引导页→主界面等跳转场景。


六、常见问题解析

❗ 问题 1:页面跳转后返回无效

  • 确保调用的是 Navigator.pop(context) 而非误写为 pop()
  • 页面跳转方式是否正确(命名 / 非命名)

❗ 问题 2:路由未注册导致崩溃

报错:Could not find a generator for route ...

解决方案:
  • 检查是否漏在 routesonGenerateRoute 中注册
  • 确保路由路径字符串一致

❗ 问题 3:传参报错(arguments 为 null 或类型错误)

  • 传参使用 Navigator.pushNamed(..., arguments: xxx)
  • 接收参数需使用 ModalRoute.of(context)?.settings.arguments,并做类型断言/判断
  • 对参数为空做容错处理