路由系统
路由介绍
Flutter 中的路由通俗的讲就是页面跳转。在 Flutter 中通过 Navigator 组件管理路由导航。 并提供了管理堆栈的方法。如:Navigator.push 和 Navigator.pop Flutter 中给我们提供了两种配置路由跳转的方式:1、基本路由 2、命名路由
普通路由
比如我们现在想从 HomePage 组件跳转到 SearchPage 组件。
需要在 HomPage 中引入 search.dart
import 'package:flutter/material.dart';
import './search.dart';
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
return Center(
child: Column(
children: [
const Text('HomePage'),
ElevatedButton(
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => const SearchPage()));
},
child: const Text('跳转到搜索页面'))
],
),
);
}
}
search.dart
import 'package:flutter/material.dart';
class SearchPage extends StatefulWidget {
const SearchPage({super.key});
@override
State<SearchPage> createState() => _SearchPageState();
}
class _SearchPageState extends State<SearchPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('SearchPage'),
),
body: const Center(
child: Text('SearchPage'),
),
);
}
}
普通路由跳转传值
跳转传值和调用组件传值的实现方法是一样的
//home.dart
import 'package:flutter/material.dart';
import './search.dart';
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
return Center(
child: Column(
children: [
const Text('HomePage'),
ElevatedButton(
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => const SearchPage(
title: "home页面来的",
)));
},
child: const Text('跳转到搜索页面'))
],
),
);
}
}
//searh.dart
import 'package:flutter/material.dart';
class SearchPage extends StatefulWidget {
final String title;
const SearchPage({super.key, this.title = "SearchPage"});
@override
State<SearchPage> createState() => _SearchPageState();
}
class _SearchPageState extends State<SearchPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: const Center(
child: Text('SearchPage'),
),
);
}
}
命名路由
注册路由
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Tabs',
theme: ThemeData(
primarySwatch: Colors.blue,
),
initialRoute: '/',
routes: {
'/': (context) => const HomePage(),
'/search': (context) => const SearchPage(),
'/profile': (context) => const ProfilePage(),
'/user': (context) => const UserPage(),
'/settings': (context) => const SettingsPage(),
},
// home: const Tabs(),
);
}
}
跳转命名路由
ElevatedButton(
onPressed: () {
Navigator.pushNamed(context, '/search');
},
child: const Text('命名路由跳转到搜索页面')
),
命名路由传值
定义路由对象
//1定义map类型的routes
final Map routes = {
'/': (context) => const Tabs(),
'/search': (context) => const SearchPage(),
'/profile': (context, {arguments}) => ProfilePage(arguments: arguments),
'/user': (context) => const UserPage(),
'/settings': (context) => const SettingsPage(),
};
MaterialApp 设置
//2注册路由表
onGenerateRoute: (RouteSettings settings) {
// 获取name参数并匹配路由表
final String? name = settings.name;
final Function? pageContentBuilder = routes[name];
// 若匹配到路由表,返回对应的PageRoute
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;
},
完整设置
import 'package:flutter/material.dart';
class ProfilePage extends StatefulWidget {
final Map arguments;
const ProfilePage({super.key, required this.arguments});
@override
State<ProfilePage> createState() => _ProfilePageState();
}
class _ProfilePageState extends State<ProfilePage> {
@override
void initState() {
super.initState();
print(widget.arguments);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('ProfilePage'),
),
body: Center(
child: Text('ProfilePage'),
),
);
}
}
页面传值
ElevatedButton(
onPressed: () {
Navigator.pushNamed(context, '/profile', arguments: {
"title": "搜索页面",
});
},
child: const Text('命名路由传参跳转到Profile页面'),
),
页面接值
import 'package:flutter/material.dart';
class ProfilePage extends StatefulWidget {
final Map arguments;
const ProfilePage({super.key, required this.arguments});
@override
State<ProfilePage> createState() => _ProfilePageState();
}
class _ProfilePageState extends State<ProfilePage> {
@override
void initState() {
super.initState();
print(widget.arguments);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('ProfilePage'),
),
body: Center(
child: Text('ProfilePage'),
),
);
}
}
组件化路由
新建 routers/routers.dart 配置路由
import 'package:flutter/material.dart';
import '../pages/tabs.dart';
import '../pages/tabs/search.dart';
import '../pages/tabs/profile.dart';
import '../pages/tabs/user.dart';
import '../pages/tabs/settings.dart';
//1定义map类型的routes
final Map routes = {
'/': (context) => const Tabs(),
'/search': (context) => const SearchPage(),
'/profile': (context, {arguments}) => ProfilePage(arguments: arguments),
'/user': (context) => const UserPage(),
'/settings': (context) => const SettingsPage(),
};
var onGenerateRoute = (RouteSettings settings) {
// 获取name参数并匹配路由表
final String? name = settings.name;
final Function? pageContentBuilder = routes[name];
// 若匹配到路由表,返回对应的PageRoute
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;
};
引用路由
import 'package:flutter/material.dart';
import './routers/routers.dart';
void main(List<String> args) {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Tabs',
theme: ThemeData(
primarySwatch: Colors.blue,
),
initialRoute: '/',
onGenerateRoute: onGenerateRoute,
//2注册路由表
);
}
}
返回上级路由
Navigator.of(context).pop();
替换路由
比如我们从用户中心页面跳转到了 registerFirst 页面,然后从 registerFirst 页面通过 pushReplacementNamed 跳转到了 registerSecond 页面。这个时候当我们点击 registerSecond 的返回按钮的时候它会直接返回到用户中心。
Navigator.of(context).pushReplacementNamed('/registerSecond');
返回到根路由
比如我们从用户中心跳转到 registerFirst 页面,然后从 registerFirst 页面跳转到 registerSecond 页面,然后从 registerSecond 跳转到了 registerThird 页面。这个时候我们想的是 registerThird 注册成功后返回到用户中心。 这个时候就用到了返回到根路由的方法。
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(builder: (BuildContext context) {
return const Tabs();
}), (route) => false);
路由跳转网格
Material 组件库中提供了一个 MaterialPageRoute 组件,它可以使用和平台风格一致的路由切换动画,如在 iOS 上会左右滑动切换,而在 Android 上会上下滑动切换 , CupertinoPageRoute 是 Cupertino 组件库提供的 iOS 风格的路由切换组件如果在 Android 上也想使用左右切换风格,可以使用 CupertinoPageRoute。
routers.dart 中引入 cupertino.dart
import 'package:flutter/cupertino.dart';
MaterialPageRoute 改为 CupertinoPageRoute
import 'package:flutter/cupertino.dart';
import '../pages/tabs.dart';
import '../pages/tabs/search.dart';
import '../pages/tabs/profile.dart';
import '../pages/tabs/user.dart';
import '../pages/tabs/settings.dart';
//1定义map类型的routes
final Map routes = {
'/': (context) => const Tabs(),
'/search': (context) => const SearchPage(),
'/profile': (context, {arguments}) => ProfilePage(arguments: arguments),
'/user': (context) => const UserPage(),
'/settings': (context) => const SettingsPage(),
};
var onGenerateRoute = (RouteSettings settings) {
// 获取name参数并匹配路由表
final String? name = settings.name;
final Function? pageContentBuilder = routes[name];
// 若匹配到路由表,返回对应的PageRoute
if (pageContentBuilder != null) {
if (settings.arguments != null) {
final Route route = CupertinoPageRoute(
builder: (context) =>
pageContentBuilder(context, arguments: settings.arguments));
return route;
} else {
final Route route =
CupertinoPageRoute(builder: (context) => pageContentBuilder(context));
return route;
}
}
return null;
};
全局主题配置
import 'package:flutter/material.dart';
import './routers/routers.dart';
void main(List<String> args) {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Tabs',
//全局主题
theme: ThemeData(
primarySwatch: Colors.blue,
appBarTheme: const AppBarTheme(
centerTitle: true,
)),
initialRoute: '/',
onGenerateRoute: onGenerateRoute,
//2注册路由表
);
}
}