flutter-implementing-navigation-and-routing by flutter/skills
npx skills add https://github.com/flutter/skills --skill flutter-implementing-navigation-and-routingActivity 或 iOS 中的 ViewController。Navigator(命令式)。它管理一个 Route 对象栈。Router(声明式)。MaterialApp.routes 和 )。它们具有僵化的深度链接行为,并且不支持浏览器的前进按钮。请改用像 这样的路由包。广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
Navigator.pushNamedgo_router使用 Navigator widget,通过平台特定的过渡动画(MaterialPageRoute 或 CupertinoPageRoute)来推送和弹出路由。
Navigator.push(context, route) 导航到新路由。Navigator.pop(context) 返回到上一个路由。Navigator.pushReplacement() 替换当前路由,或使用 Navigator.pushAndRemoveUntil() 根据条件清空栈。PageRoute 的 settings: RouteSettings(arguments: data) 参数传递数据,并使用 ModalRoute.of(context)!.settings.arguments 提取。pop 方法:Navigator.pop(context, resultData)。在推送方等待结果:final result = await Navigator.push(...)。对于需要深度链接、Web URL 支持或复杂路由的应用,通过像 go_router 这样的声明式路由包来实现 Router API。
MaterialApp 切换到 MaterialApp.router。Navigator 的路由器配置。context.go('/path'))。实现嵌套导航,以独立于顶层的全局导航器来管理屏幕的子流程(例如,多步骤设置流程或持久的底部导航标签页)。
Navigator widget。Navigator 分配一个 GlobalKey<NavigatorState> 以便以编程方式控制它。Navigator 内实现 onGenerateRoute 回调以解析子路由。PopScope 拦截硬件返回按钮按下事件,以防止顶层导航器过早弹出整个嵌套流程。复制此清单,以便在实现基本屏幕过渡时跟踪进度:
Navigator.push()。MaterialPageRoute 或 CupertinoPageRoute 中。Navigator.pop() 以返回。在设置应用范围的路由时,请使用此条件工作流程:
MaterialApp 和 Navigator.push()。go_router 包。MaterialApp 更改为 MaterialApp.router。GoRouter 配置。Navigator.push() 替换为 context.go() 或 context.push()。在构建多步骤子流程(例如 IoT 设备设置)时,运行此工作流程:
GlobalKey<NavigatorState>。build 方法中返回一个 Navigator widget,并传入该 key。Navigator 中实现 onGenerateRoute,将字符串路径映射到特定的步骤 widget。Scaffold 包装在 PopScope 中以处理返回按钮拦截(例如,提示“您确定要退出设置吗?”)。navigatorKey.currentState!.pushNamed() 在流程中推进步骤。// 1. 定义数据模型
class Todo {
final String title;
final String description;
const Todo(this.title, this.description);
}
// 2. 源屏幕
class TodosScreen extends StatelessWidget {
final List<Todo> todos;
const TodosScreen({super.key, required this.todos});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Todos')),
body: ListView.builder(
itemCount: todos.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(todos[index].title),
onTap: () {
// 推送并通过构造函数传递数据
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailScreen(todo: todos[index]),
),
);
},
);
},
),
);
}
}
// 3. 目标屏幕
class DetailScreen extends StatelessWidget {
final Todo todo;
const DetailScreen({super.key, required this.todo});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(todo.title)),
body: Padding(
padding: const EdgeInsets.all(16),
child: Text(todo.description),
),
);
}
}
class SetupFlow extends StatefulWidget {
final String initialRoute;
const SetupFlow({super.key, required this.initialRoute});
@override
State<SetupFlow> createState() => _SetupFlowState();
}
class _SetupFlowState extends State<SetupFlow> {
final _navigatorKey = GlobalKey<NavigatorState>();
void _exitSetup() => Navigator.of(context).pop();
@override
Widget build(BuildContext context) {
return PopScope(
canPop: false,
onPopInvokedWithResult: (didPop, _) async {
if (didPop) return;
// 拦截返回按钮以防止意外退出
_exitSetup();
},
child: Scaffold(
appBar: AppBar(title: const Text('Setup')),
body: Navigator(
key: _navigatorKey,
initialRoute: widget.initialRoute,
onGenerateRoute: _onGenerateRoute,
),
),
);
}
Route<Widget> _onGenerateRoute(RouteSettings settings) {
Widget page;
switch (settings.name) {
case 'step1':
page = StepOnePage(
onComplete: () => _navigatorKey.currentState!.pushNamed('step2'),
);
break;
case 'step2':
page = StepTwoPage(onComplete: _exitSetup);
break;
default:
throw StateError('Unexpected route name: ${settings.name}!');
}
return MaterialPageRoute(
builder: (context) => page,
settings: settings,
);
}
}
每周安装量
1.9K
代码仓库
GitHub 星标数
784
首次出现
11 天前
安全审计
安装于
codex1.9K
gemini-cli1.9K
opencode1.9K
github-copilot1.9K
cursor1.9K
kimi-cli1.9K
Activity in Android or a ViewController in iOS.Navigator (Imperative) for small applications without complex deep linking requirements. It manages a stack of Route objects.Router (Declarative) for applications with advanced navigation, web URL synchronization, and specific deep linking requirements.MaterialApp.routes and Navigator.pushNamed) for most applications. They have rigid deep linking behavior and do not support the browser forward button. Use a routing package like go_router instead.Use the Navigator widget to push and pop routes using platform-specific transition animations (MaterialPageRoute or CupertinoPageRoute).
Navigator.push(context, route).Navigator.pop(context).Navigator.pushReplacement() to replace the current route, or Navigator.pushAndRemoveUntil() to clear the stack based on a condition.settings: RouteSettings(arguments: data) parameter of the PageRoute and extract it using ModalRoute.of(context)!.settings.arguments.pop method: Navigator.pop(context, resultData). Await the result on the pushing side: final result = await Navigator.push(...).For apps requiring deep linking, web URL support, or complex routing, implement the Router API via a declarative routing package like go_router.
MaterialApp to MaterialApp.router.Navigator automatically.context.go('/path')).Implement nested navigation to manage a sub-flow of screens (e.g., a multi-step setup process or persistent bottom navigation tabs) independently from the top-level global navigator.
Navigator widget inside the host widget.GlobalKey<NavigatorState> to the nested Navigator to control it programmatically.onGenerateRoute callback within the nested Navigator to resolve sub-routes.PopScope to prevent the top-level navigator from popping the entire nested flow prematurely.Copy this checklist to track progress when implementing a basic screen transition:
Navigator.push() in the source widget.MaterialPageRoute or CupertinoPageRoute.Navigator.pop() in the destination widget to return.Use this conditional workflow when setting up app-wide routing:
MaterialApp and Navigator.push().go_router package.MaterialApp to MaterialApp.router.GoRouter configuration with all top-level routes.Navigator.push() with context.go() or context.push().Run this workflow when building a multi-step sub-flow (e.g., IoT device setup):
GlobalKey<NavigatorState> in the host widget's state.Navigator widget in the host's build method, passing the key.onGenerateRoute in the nested Navigator to map string paths to specific step widgets.Scaffold in a PopScope to handle back-button interceptions (e.g., prompting "Are you sure you want to exit setup?").navigatorKey.currentState!.pushNamed() to advance steps within the flow.// 1. Define the data model
class Todo {
final String title;
final String description;
const Todo(this.title, this.description);
}
// 2. Source Screen
class TodosScreen extends StatelessWidget {
final List<Todo> todos;
const TodosScreen({super.key, required this.todos});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Todos')),
body: ListView.builder(
itemCount: todos.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(todos[index].title),
onTap: () {
// Push and pass data via constructor
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailScreen(todo: todos[index]),
),
);
},
);
},
),
);
}
}
// 3. Destination Screen
class DetailScreen extends StatelessWidget {
final Todo todo;
const DetailScreen({super.key, required this.todo});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(todo.title)),
body: Padding(
padding: const EdgeInsets.all(16),
child: Text(todo.description),
),
);
}
}
class SetupFlow extends StatefulWidget {
final String initialRoute;
const SetupFlow({super.key, required this.initialRoute});
@override
State<SetupFlow> createState() => _SetupFlowState();
}
class _SetupFlowState extends State<SetupFlow> {
final _navigatorKey = GlobalKey<NavigatorState>();
void _exitSetup() => Navigator.of(context).pop();
@override
Widget build(BuildContext context) {
return PopScope(
canPop: false,
onPopInvokedWithResult: (didPop, _) async {
if (didPop) return;
// Intercept back button to prevent accidental exit
_exitSetup();
},
child: Scaffold(
appBar: AppBar(title: const Text('Setup')),
body: Navigator(
key: _navigatorKey,
initialRoute: widget.initialRoute,
onGenerateRoute: _onGenerateRoute,
),
),
);
}
Route<Widget> _onGenerateRoute(RouteSettings settings) {
Widget page;
switch (settings.name) {
case 'step1':
page = StepOnePage(
onComplete: () => _navigatorKey.currentState!.pushNamed('step2'),
);
break;
case 'step2':
page = StepTwoPage(onComplete: _exitSetup);
break;
default:
throw StateError('Unexpected route name: ${settings.name}!');
}
return MaterialPageRoute(
builder: (context) => page,
settings: settings,
);
}
}
Weekly Installs
1.9K
Repository
GitHub Stars
784
First Seen
11 days ago
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
codex1.9K
gemini-cli1.9K
opencode1.9K
github-copilot1.9K
cursor1.9K
kimi-cli1.9K
React 组合模式指南:Vercel 组件架构最佳实践,提升代码可维护性
102,200 周安装
AI代码审查工具 - 自动化安全漏洞检测与代码质量分析 | 支持多领域检查清单
1,200 周安装
AI智能体长期记忆系统 - 精英级架构,融合6种方法,永不丢失上下文
1,200 周安装
AI新闻播客制作技能:实时新闻转对话式播客脚本与音频生成
1,200 周安装
Word文档处理器:DOCX创建、编辑、分析与修订痕迹处理全指南 | 自动化办公解决方案
1,200 周安装
React Router 框架模式指南:全栈开发、文件路由、数据加载与渲染策略
1,200 周安装
Nano Banana AI 图像生成工具:使用 Gemini 3 Pro 生成与编辑高分辨率图像
1,200 周安装