4. 路由
4.1 静态路由
静态路由(即命名路由)
静态路由在通过Navigator
跳转之前,需要在MaterialApp
组件内显式声明路由的名称,而一旦声明,路由的跳转方式就固定了。通过在MaterialApp
内的routes
属性进行显式声明路由的定义。
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "Flutter Demo",
theme: ThemeData(primarySwatch: Colors.blue),
// home: const Tabs(),
initialRoute: "/",
routes: {
"/": (context) => const Tabs(),
/*
也可以使用大括号的写法
"/": (context) { reutnr const Tabs() },
*/
"/s": (context) => const Search(
title: '',
)
},
);
}
}
注:使用命名路由时,home 要注释掉,使用 initialRoute
class _MessageState extends State<Message> {
@override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
// 命名路由跳转页面方式
Navigator.pushNamed(context, "/s",
arguments: {"title": "我是标题", "content": "我是内容"});
},
child: const Text("跳转搜索页面"))
],
),
);
}
}
4.2 动态路由
动态路由无需在MaterialApp
内的routes
中注册即可直接使用:RootPage —> Apage
Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext context) {
return const Search();
}
)
);
动态路由中,需要传入一个Route
,这里使用的是MaterialPageRoute
,它可以使用和平台风格一致的路由切换动画,在iOS上左右滑动切换,Android上会上下滑动切换。也可以使用CupertinoPageRoute
实现全平台的左右滑动切换。
当然也可以自定义路由切换动画,使用PageRouteBuilder
:使用FadeTransition
做一个渐入过渡动画。
使用 CupertinoPageRoute 时,需要引入 import 'package:flutter/cupertino.dart';
Navigator.of(context).push(
PageRouteBuilder(
transitionDuration: Duration(milliseconds: 250), // //动画时间为0.25秒
pageBuilder: (BuildContext context,Animation animation,
Animation secondaryAnimation){
return FadeTransition( //渐隐渐入过渡动画
opacity: animation,
child: Search()
);
}
)
);
在这之前有必要说明:
Navigator.of(context).push
和Navigator.push
两着并没有特别的区别,看源码也得知,后者其实就是调用了前者。
of
:获取Navigator
当前已经实例的状态。
4.3 跳转传值
接收值
import 'package:flutter/material.dart';
class Search extends StatefulWidget {
final String title;
final String content;
const Search({super.key, required this.title, this.content = "默认内容"});
@override
State<Search> createState() => _SearchState();
}
class _SearchState extends State<Search> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
// 通过 widget 进行取值的操作
title: Text(widget.title),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(widget.content),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () {
Navigator.pop(context);
},
child: const Text("返回上一页"))
],
),
);
}
}
传值
import 'package:flutter/material.dart';
import '../search.dart';
class Message extends StatefulWidget {
const Message({super.key});
@override
State<Message> createState() => _MessageState();
}
class _MessageState extends State<Message> {
@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 Search(
title: '搜索Title',
content: "我是传过去的值",
);
}));
},
child: const Text("跳转搜索页面"))
],
),
);
}
}
4.4 pop
返回当前路由栈的上一个界面。
Navigator.pop(context);
4.5 替换路由
第一页面 -> 第二页面 -> 第三页面。
在第二个界面中,使用 pushReplacementNamed,跳转到第三个页面,在第三个页面点返回时,就回到了第一个页面。而不是第二个。
Navigator.of(context).pushReplacementNamed("/C");
4.6 返回跟路由
参考:https://www.jianshu.com/p/beda41170b60
// 移除全部
Navigator.pushAndRemoveUntil(context, MaterialPageRoute(
builder: (context) {
return const Tabs();
},
), (route) => false);
// 或者
// 移除全部
Navigator.of(context).pushNamedAndRemoveUntil("/", (route) => false);
网友评论