🔥 本文由 程序喵正在路上 原创,CSDN首发!
💖 系列专栏:Flutter学习
🌠 首发时间:2024年5月27日
🦋 欢迎关注🖱点赞👍收藏🌟留言🐾
路由介绍
路由,通俗地讲就是页面跳转。在 Flutter 中,我们通过 Navigator 组件来管理路由导航, Navigator 组件中提供了管理堆栈的方法。如:Navigator.push 跳转到某个路由和 Navigator.pop 返回到某个路由
Flutter 中给我们提供了两种配置路由跳转的方式:
- 普通路由
- 命名路由
普通路由
举例:比如我们现在想从 HomePage 组件跳转到 SearchPage 组件,应该如何使用普通路由实现呢?
-
我们先在 pages 目录下简单写一个 search.dart
import 'package:flutter/material.dart'; class SearchPage extends StatefulWidget { const SearchPage({super.key}); State<SearchPage> createState() => _SearchPageState(); } class _SearchPageState extends State<SearchPage> { Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text("搜索页面"), ), body: const Center( child: Text("搜索页面"), ), ); } } -
在 home.dart 中引入 search.dart
import '../search.dart'; -
在
HomePage中通过下面方法跳转import 'package:flutter/material.dart'; import '../search.dart'; class HomePage extends StatefulWidget { const HomePage({super.key}); State<HomePage> createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { Widget build(BuildContext context) { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ ElevatedButton( onPressed: () { Navigator.of(context).push( //调用push MaterialPageRoute(builder: (context) { return const SearchPage(); }), ); }, child: const Text("跳转到搜索页面"), ), ], ), ); } } -
点击按钮,就会自动跳转到搜索页面

普通路由跳转传值
跳转传值的意思是在跳转页面的同时传一些值给要跳转的页面,比如页面标题什么的。
我们在 search.dart 中添加一个变量 title 来接收传值,并将其设置为页面导航栏的标题,同时,我们还增加了一个可以返回上个页面的浮动按钮
import 'package:flutter/material.dart';
class SearchPage extends StatefulWidget {
final String title; //用于接收传值
const SearchPage({super.key, required this.title});
State<SearchPage> createState() => _SearchPageState();
}
class _SearchPageState extends State<SearchPage> {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title), //通过widget.来调用传过来的值
),
floatingActionButton: FloatingActionButton(
onPressed: () {
//返回到上一页
Navigator.pop(context);
},
child: const Icon(Icons.home),
),
body: const Center(
child: Text("搜索页面"),
),
);
}
}
当然,在跳转页面的时候就必须传入值了

命名路由
当跳转的页面多了之后,为了方便管理这些页面,这个时候我们就需要用到命名路由。
命名路由的使用很简单,具体步骤如下:
-
在 main.dart 中引入项目中所有需要跳转的页面,引入后,在其它文件中就不用再引入了,可以直接使用。比如我们有 search.dart 和 form.dart 两个页面需要跳转:
import './pages/search.dart'; import './pages/form.dart';两个页面除了名字都是一样的
import 'package:flutter/material.dart'; class SearchPage extends StatefulWidget { const SearchPage({super.key}); State<SearchPage> createState() => _SearchPageState(); } class _SearchPageState extends State<SearchPage> { Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text("搜一搜"), ), floatingActionButton: FloatingActionButton( onPressed: () { //返回到上一页 Navigator.pop(context); }, child: const Icon(Icons.home), ), body: const Center( child: Text("搜索页面"), ), ); } } -
在 main.dart 中配置所有路由和初始路由,此时我们不用再配置
home属性import 'package:flutter/material.dart'; import 'pages/tabs.dart'; import './pages/search.dart'; import './pages/form.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), debugShowCheckedModeBanner: false, initialRoute: "/", routes: { "/": (context) => const Tabs(), "/search": (context) => const SearchPage(), "/form": (context) => const FormPage(), }, ); } }这两种书写方式的效果是一样的
"/form": (context) => const FormPage(title: "表单") "/form": (context) { return const FormPage(title: "表单"); } -
然后我们在 home.dart 中进行页面的跳转,不用引入,而且只需要一行代码
import 'package:flutter/material.dart'; class HomePage extends StatefulWidget { const HomePage({super.key}); State<HomePage> createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { Widget build(BuildContext context) { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ ElevatedButton( onPressed: () { Navigator.pushNamed(context, "/search"); }, child: const Text("命名路由跳转搜索页面"), ), const SizedBox(height: 30), ElevatedButton( onPressed: () { Navigator.pushNamed(context, "/form"); }, child: const Text("命名路由跳转表单页面"), ), ], ), ); } }
命名路由跳转传值
具体步骤:
- 定义路由
- 配置 onGenerateRoute
- 定义页面接收 arguments 传参
- 跳转页面实现传参
- 打印验证传值是否成功
完整代码:
main.dart
import 'package:flutter/material.dart';
import 'pages/tabs.dart';
import './pages/search.dart';
import './pages/form.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
//1. 定义路由
Map routes = {
"/": (context) => const Tabs(),
"/search": (context, {arguments}) =>
SearchPage(arguments: arguments), //定义arguments后, 需要传入arguments
"/form": (context) => const FormPage(),
};
MyApp({super.key});
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
debugShowCheckedModeBanner: false,
initialRoute: "/",
//2. 配置onGenerateRoute,固定写法
onGenerateRoute: (settings) {
// 统一处理
final String? name = settings.name;
final Function? pageContentBuilder = routes[name];
if (pageContentBuilder != null) {
if (settings.arguments != null) {
final Route route = MaterialPageRoute(
builder: (context) =>
pageContentBuilder(context, arguments: settings.arguments));
return route;
} else {
final Route route = MaterialPageRoute(
builder: (context) => pageContentBuilder(context));
return route;
}
}
return null;
},
);
}
}
search.dart
import 'package:flutter/material.dart';
class SearchPage extends StatefulWidget {
//3. 定义页面接收arguments传参
final Map arguments;
const SearchPage({super.key, required this.arguments});
State<SearchPage> createState() => _SearchPageState();
}
class _SearchPageState extends State<SearchPage> {
void initState() {
super.initState();
//5. 打印传过来的值
print(widget.arguments);
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("搜一搜"),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
//返回到上一页
Navigator.pop(context);
},
child: const Icon(Icons.home),
),
body: const Center(
child: Text("搜索页面"),
),
);
}
}
home.dart
import 'package:flutter/material.dart';
class HomePage extends StatefulWidget {
const HomePage({super.key});
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
//4. 跳转页面实现传参
Navigator.pushNamed(context, "/search", arguments: {
"title": "搜索页面",
"aid": 20,
});
},
child: const Text("命名路由跳转传值"),
),
const SizedBox(height: 30),
ElevatedButton(
onPressed: () {
Navigator.pushNamed(context, "/form");
},
child: const Text("命名路由跳转表单页面"),
),
],
),
);
}
}
启动项目后,当我们点击第一个按钮时,终端打印出我们传递过去的参数,即为成功:

将命名路由单独抽离
-
在 lib 目录下新建 routers 文件夹,在文件夹下新建文件 router.dart,然后将 main.dart 中和路由有关的代码复制过来
import 'package:flutter/material.dart'; import '../pages/tabs.dart'; import '../pages/search.dart'; import '../pages/form.dart'; //1. 定义路由 final Map routes = { "/": (context) => const Tabs(), "/search": (context, {arguments}) => SearchPage(arguments: arguments), //定义arguments后, 需要传入arguments "/form": (context) => const FormPage(), }; //2. 配置onGenerateRoute,固定写法 var onGenerateRoute = (settings) { // 统一处理 final String? name = settings.name; final Function? pageContentBuilder = routes[name]; if (pageContentBuilder != null) { if (settings.arguments != null) { final Route route = MaterialPageRoute( builder: (context) => pageContentBuilder(context, arguments: settings.arguments)); return route; } else { final Route route = MaterialPageRoute(builder: (context) => pageContentBuilder(context)); return route; } } return null; }; -
修改 main.dart
import 'package:flutter/material.dart'; import './routers/router.dart'; //引入 void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), debugShowCheckedModeBanner: false, initialRoute: "/", onGenerateRoute: onGenerateRoute, ); } }
返回上一级路由
Navigator.of(context).pop();
替换路由
一般在一个页面跳转后,我们点击返回按钮,只能返回到上一级页面。如果我们想让其直接返回到上上级页面,跳过上一级页面,这个时候就需要用到替换路由,我们需要将被跳过的页面中的跳转语句改为类似如下:
Navigator.of(context).pushReplacementNamed('/registerSecond');
返回到根路由
当跳转页面太多的时候,替换路由并不能让我们在某个页面直接返回到最开始的那个页面,这个时候我们就需要用到跟路由的知识。
首先,我们需要在需要跳转的页面中引入最开始那个页面,然后将其中的跳转语句改为类似如下:
//返回到根页面
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(builder: (BuildContext context) {
return const Tabs();
}), (route) => false);
Android和Ios使用同样风格的路由跳转
Material 组件库中提供了一个 MaterialPageRoute 组件,它可以使用和平台风格一致的路由切换动画,如在 iOS 上会左右滑动切换,而在 Android 上会上下滑动切换,CupertinoPageRoute 是 Cupertino 组件库提供的 iOS 风格的路由切换组件,如果在 Android 上也想使用左右切换风格,我们可以使用 CupertinoPageRoute。
具体步骤如下:
- 在 router.dart 中删掉
import 'package:flutter/material.dart';,然后引入Cupertino组件,即import 'package:flutter/cupertino.dart'; - 将 router.dart 代码中的 MaterialPageRoute 改为 CupertinoPageRoute 即可
2126

被折叠的 条评论
为什么被折叠?



