携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第26天,点击查看活动详情
本文主要介绍下Navigate的使用
1. Navigator
Navigator 是一个组件,管理和维护一个基于堆栈的历史记录,通过 push 和 pop 进行页面的跳转。
class PageA extends StatelessWidget {
const PageA({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(color: Colors.orangeAccent,),
floatingActionButton: FloatingActionButton(onPressed: () { Navigator.of(context).push(MaterialPageRoute(builder: (context) => PageB())); },),
);
}
}
页面B
class PageB extends StatelessWidget {
const PageB({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('页面B'),),
body: Container(color: Colors.red,),
);
}
}
当应用程序位于A页面时,路由堆栈中只有A,点击按钮跳转到B页面,路由堆栈中有 B 和 A,且 B 处于栈顶。
通过push进栈,pop出栈。
当我们的栈只有一个的时候进行pop
child: ElevatedButton(
onPressed: (){
if(Navigator.of(context).canPop()){
Navigator.of(context).pop();
}
},
2. pushNamed
pushNamed 是命名路由的方式,需要在 MaterialApp 中配置路由名称:
MaterialApp(
title: 'Router Demo',
routes: <String, WidgetBuilder>{
'/A': (context) => PageA(),
'/B': (context) => PageB(),
},
home: Scaffold(
body: PageA(),
),
)
跳转
ElevatedButton(
onPressed: (){
Navigator.of(context).pushNamed('/B');
},
child: Text('push B'),
)
当我们有三个页面的时候,从B push C
ElevatedButton(
onPressed: (){
Navigator.of(context).pushReplacementNamed('/C');
},
child: Text('push C'),
)
C返回的时候直接到达页面A
- popAndPushNamed
ElevatedButton(
onPressed: (){
// Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (context)=>PageC()));
Navigator.of(context).popAndPushNamed('/C');
},
child: const Text('push B'),
popAndPushNamed 路由堆栈和 pushReplacementNamed 是一样,唯一的区别就是 popAndPushNamed 有 B 页面退出动画。
popAndPushNamed 和 pushReplacementNamed 使当前页面不在路由堆栈中,所以通过 pop 无法返回此页面。
适用场景:
1. **欢迎页面**:应用程序打开后首先进入欢迎界面,然后进入首页,进入首页后不应该再进入欢迎界面。
2. **登录页面**:登录成功后进入相关页面,此时按返回按钮,不应再进入登录页面。
pushNamedAndRemoveUntil
适用于特定入口场景,比如我们在登陆流程中进行注册或者绑定,之后我们就不希望在返回该路径
pushNamedAndRemoveUntil进入 D 页面同时删除路由堆栈中直到 /B 的路由,C 页面代码:
Navigator.of(context).pushNamedAndRemoveUntil('/D', ModalRoute.withName('/B'));
A->B->C->D之后 返回B
3. 传递数据
- 通过构造函数
class PageB extends StatelessWidget {
final String title;
const PageB({Key? key,required this.title}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(title),),
body: Center(
child: ElevatedButton(
onPressed: (){
// Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (context)=>PageC()));
Navigator.of(context).popAndPushNamed('/C');
},
child: const Text('push B'),
),
),
);
}
}
跳转
Navigator.of(context).push(MaterialPageRoute(builder: (context) => const PageB(title: "页面B",)));
- 通过命名路由设置参数的方式:
FloatingActionButton(onPressed: (){
Navigator.of(context).pop();
},
child: Text('${ModalRoute.of(context)?.settings.arguments}'),
)
- 接受
Navigator.of(context).pop("你好");
跳转页面接受
class PageB extends StatefulWidget {
final String title;
const PageB({Key? key,required this.title}) : super(key: key);
@override
State<PageB> createState() => _PageBState();
}
class _PageBState extends State<PageB> {
var arg = '"';
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(arg),),
body: Center(
child: ElevatedButton(
onPressed: () async{
// Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (context)=>PageC()));
var result = await Navigator.of(context).pushNamed('/C',arguments: "hello") as String;
setState(() {
arg = result;
});
},
child: const Text('push B'),
),
),
);
}
}