【笔记】Flutter的路由

前言

Flutter的路由学习笔记

基本路由

基本路由跳转

  • 通过Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext context) { return const Page(); }));方法实现基本路由跳转
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import 'package:flutter/material.dart';

void main() {
runApp(MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text("文本内容"),
),
body: const App(),
),
));
}

class App extends StatefulWidget {
const App({super.key});

@override
State<App> createState() => _AppState();
}

class _AppState extends State<App> {
@override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
// 定义页面跳转
Navigator.of(context).push(
MaterialPageRoute(
builder: (BuildContext context) {
return const Page();
}
)
);
},
child: const Text("文本内容"))
],
),
);
}
}

class Page extends StatelessWidget {
const Page({super.key});

@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text("文本内容"),
),
body: const Center(
child: Text(
"文本内容",
textDirection: TextDirection.ltr,
),
),
),
);
}
}

基本路由传值

  • 定义一个成员变量,用于接收构造方法传递的值
  • 通过widget.成员变量名获取变量的值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
import 'package:flutter/material.dart';

void main() {
runApp(MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text("文本内容"),
),
body: const App(),
),
));
}

class App extends StatefulWidget {
const App({super.key});

@override
State<App> createState() => _AppState();
}

class _AppState extends State<App> {
@override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (BuildContext context) {
// 3. 通过构造方法传值
return const Page(value: "传递的值", id: 1,);
}
)
);
},
child: const Text("文本内容"))
],
),
);
}
}

class Page extends StatefulWidget {

// 1. 定义成员属性
final String value;
final int id;

const Page({
super.key,
// 2. 定义成员属性初始化
this.value = "默认值",
required this.id
});

@override
State<Page> createState() => _PageState();
}

class _PageState extends State<Page> {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
// 4. 通过成员属性使用传递的值
title: Text("${widget.value}-${widget.id}"),
),
body: const Center(
child: Text(
"文本内容",
textDirection: TextDirection.ltr,
),
),
),
);
}
}

命名路由

通过routes定义路由

命名路由跳转

  • 通过routes定义所有页面的路由
  • 当需要跳转页面时,通过Navigator.pushNamed(context, "/路由");方法实现命名路由跳转

initialRoute:初始页面路由
routes:所有路由

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
import 'package:flutter/material.dart';

void main() {
runApp(const Router());
}

class Router extends StatefulWidget {
const Router({super.key});

@override
State<Router> createState() => _RouterState();
}

class _RouterState extends State<Router> {
@override
Widget build(BuildContext context) {
return MaterialApp(
initialRoute: "/app",
// 1. 定义路由
routes: {
"/app": (context) => const App(),
"/page": (context) => const Page(),
},
);
}
}

class App extends StatefulWidget {
const App({super.key,});

@override
State<App> createState() => _AppState();
}

class _AppState extends State<App> {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text("文本内容"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
// 2. 定义页面跳转
Navigator.pushNamed(context, "/page");
},
child: const Text("文本内容"),
)
],
),
),
),
);
}
}

class Page extends StatefulWidget {
const Page({super.key,});

@override
State<Page> createState() => _PageState();
}

class _PageState extends State<Page> {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text("文本内容"),
),
body: const Center(
child: Text(
"文本内容",
textDirection: TextDirection.ltr,
),
),
),
);
}
}

通过onGenerateRoute定义路由

命名路由跳转

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import 'package:flutter/material.dart';

void main() {
runApp(Router());
}

class Router extends StatelessWidget {

// 1. 定义路由
Map routes = {
"/app": (context) => const App(),
"/page": (context) => const Page(),
};

Router({super.key});

@override
Widget build(BuildContext context) {
return MaterialApp(
initialRoute: "/app",
// 2. 定义路由的跳转
onGenerateRoute: (RouteSettings 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;
},
);
}
}

class App extends StatefulWidget {
const App({super.key});

@override
State<App> createState() => _AppState();
}

class _AppState extends State<App> {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text("文本内容"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
// 3. 定义页面跳转
Navigator.pushNamed(context, "/page");
},
child: const Text("文本内容")
)
],
),
),
),
);
}
}

class Page extends StatefulWidget {
const Page({super.key});

@override
State<Page> createState() => _PageState();
}

class _PageState extends State<Page> {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text("文本内容"),
),
body: const Text("文本内容"),
),
);
}
}

命名路由传值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
import 'package:flutter/material.dart';

void main() {
runApp(Router());
}

class Router extends StatelessWidget {

Map routes = {
"/app": (context) => const App(),
// 3. 定义构造方法传值方式
"/page": (context, {arguments}) => Page(arguments: arguments),
};

Router({super.key});

@override
Widget build(BuildContext context) {
return MaterialApp(
initialRoute: "/app",
onGenerateRoute: (RouteSettings 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;
},
);
}
}

class App extends StatefulWidget {
const App({super.key});

@override
State<App> createState() => _AppState();
}

class _AppState extends State<App> {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text("文本内容"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
// 4. 通过构造方法传值
Navigator.pushNamed(context, "/page", arguments: {
"key": "value",
"id": 1
});
},
child: const Text("文本内容")
)
],
),
),
),
);
}
}

class Page extends StatefulWidget {

// 1. 定义成员属性
final Map arguments;

const Page({
super.key,
// 2. 定义成员属性初始化
required this.arguments
});

@override
State<Page> createState() => _PageState();
}

class _PageState extends State<Page> {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
// 5. 通过成员属性使用传递的值
title: Text("${widget.arguments['key']}-${widget.arguments['id']}"),
),
body: const Text("文本内容"),
),
);
}
}

路由跳转

压入一个路由

1
Navigator.pushNamed(context, "/路由路径");

弹出一个路由

1
Navigator.of(context).pop();

弹出一个路由并压入一个路由(替换路由)

  • 把当前页面的路由替换为另一个页面的路由,此时跳转上一级路由时不会跳转到被替换的页面,而是被替换的页面的上一级页面
1
Navigator.of(context).pushReplacementNamed("/路由路径");

清空栈内所有路由并压入一个路由(跳转到根)

1
2
3
4
5
6
7
8
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(
builder: (BuildContext context) {
return 根页面();
}
),
(route) => false
);

强制使用相同的路由跳转风格

  • material包中提供的路由跳转风格,根据Android设备和IOS设备的不同,采用不同的风格跳转路由

Android设备采用从底至顶的风格跳转路由
IOS设备采用从右至左的风格跳转路由

强制在任何设备上都采用IOS的路由跳转风格

  1. import 'package:flutter/material.dart'改为import 'package:flutter/cupertino.dart'
  2. MaterialPageRoute改为CupertinoPageRoute

完成

参考文献

哔哩哔哩——筱筱知晓