Loading...
Loading...
Handles routing, navigation, and deep linking in a Flutter application. Use when moving between screens or setting up URL-based navigation.
npx skill4agent add flutter/skills flutter-implementing-navigation-and-routingActivityViewControllerNavigatorRouteRouterMaterialApp.routesNavigator.pushNamedgo_routerNavigatorMaterialPageRouteCupertinoPageRouteNavigator.push(context, route)Navigator.pop(context)Navigator.pushReplacement()Navigator.pushAndRemoveUntil()settings: RouteSettings(arguments: data)PageRouteModalRoute.of(context)!.settings.argumentspopNavigator.pop(context, resultData)final result = await Navigator.push(...)Routergo_routerMaterialAppMaterialApp.routerNavigatorcontext.go('/path')NavigatorGlobalKey<NavigatorState>NavigatoronGenerateRouteNavigatorPopScopeNavigator.push()MaterialPageRouteCupertinoPageRouteNavigator.pop()MaterialAppNavigator.push()go_routerMaterialAppMaterialApp.routerGoRouterNavigator.push()context.go()context.push()GlobalKey<NavigatorState>NavigatorbuildonGenerateRouteNavigatorScaffoldPopScopenavigatorKey.currentState!.pushNamed()// 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});
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});
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});
State<SetupFlow> createState() => _SetupFlowState();
}
class _SetupFlowState extends State<SetupFlow> {
final _navigatorKey = GlobalKey<NavigatorState>();
void _exitSetup() => Navigator.of(context).pop();
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,
);
}
}