Flutter 中页面跳转通过 Navigator
和 Route
来实现。
一、页面跳转
1,常规路由页面跳转
- 跳转到
JumpPage();
,需要用push
方法,将JumpPage();
入栈
Navigator.of(context).push(
MaterialPageRoute(builder: (context) {
return JumpPage();//返回的是需要跳转单页面
},));
- 返回上一级,出栈
//返回
Navigator.of(context).pop(this);
2,命名路由页面跳转
路由名称通常使用路径结构:“ /a/b/c ”,主页默认为 “ / ”。
Navigator.pushNamed(context, '/xxxx');
, 需要调用这个push方法通常写法如下:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(primarySwatch: Colors.blue, accentColor: Colors.blue),
home: MainTab(),
routes: {
///定义 /jump 对应 JumpPage(); 页面
'/jump':(context)=>JumpPage(),
}
);
}
}
class MainTab extends StatefulWidget {
@override
_MainTabState createState() => _MainTabState();
}
class _MainTabState extends State<MainTab> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('命名路由'),
),
body: Column(
children: <Widget>[
RaisedButton(
onPressed: () {
//命名路由跳转,使用 “ /jump ” 来替代
Navigator.pushNamed(context, '/jump');
},
child: Text('命名路由,点击跳转'),
),
],
),
);
}
}
二、页面传值
1,通常传值,都是通过构造方法来传值例如:
在跳转的页面定义一个构造函数 包含可选参数data
class JumpPage extends StatefulWidget {
var data;
JumpPage({this.data});
@override
_JumpPageState createState() => _JumpPageState(data: this.data);
}
//省略部分代码
....
跳转的时候,可以这样传入:
//路由跳转
Navigator.of(context).push(MaterialPageRoute(
builder: (context) {
return JumpPage(data: '传到第二个页面数据',);
},
));
2,命名路由传值
命名路由可以通过这个 arguments
来实现:
2-1 定义命名路由跳转页面
///命名路由
final routes={
'/jump_with_value':(context,{arguments})=>JumpWithValuePage(arguments:arguments),
};
2-2 使用 MaterialApp 参数 onGenerateRoute
///注意,配置这个就不能够使用上面:routes
onGenerateRoute:(RouteSettings set){
//拿到路由的名称,例如上面的 '/jump_with_value'
String name=set.name;
print(' onGenerateRoute set.name = $name');
///这里拿到的其实是:JumpPage()
Function function=this.routes[name];
if (function!=null) {
print(' onGenerateRoute function!=null');
Route route=MaterialPageRoute(
builder: (context)=>function(context,arguments:set.arguments)
);
return route;
}
return null;
}
2-3 跳转的时候,将参数放到 Navigator.pushNamed
的arguments
中:
//命名路由跳转
Navigator.pushNamed(context, '/jump_with_value',arguments:{
'name':'张三'
});
完整代码如下:
import 'package:flutter/material.dart';
import 'package:flutter_demo1/demo3_name_route/JumpWithValuePage.dart';
/// 命名路由传值
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
///命名路由
final routes={
'/jump_with_value':(context,{arguments})=>JumpWithValuePage(arguments:arguments),
};
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(primarySwatch: Colors.blue, accentColor: Colors.blue),
home: MainTab(),
// routes: this.routes,
// initialRoute: ,///初始化的时候需要加载的路由
///注意,配置这个就不能够使用上面:routes
onGenerateRoute:(RouteSettings set){
//拿到路由的名称,例如上面的 '/jump_with_value'
String name=set.name;
print(' onGenerateRoute set.name = $name');
///这里拿到的其实是:JumpPage()
Function function=this.routes[name];
if (function!=null) {
print(' onGenerateRoute function!=null');
Route route=MaterialPageRoute(
builder: (context)=>function(context,arguments:set.arguments)
);
return route;
}
return null;
} ,
);
}
}
class MainTab extends StatefulWidget {
@override
_MainTabState createState() => _MainTabState();
}
class _MainTabState extends State<MainTab> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('标题'),
),
body: Column(
children: <Widget>[
RaisedButton(
onPressed: () {
//命名路由跳转
Navigator.pushNamed(context, '/jump_with_value',arguments:{
'name':'张三'
});
},
child: Text('命名路由,点击跳转,传值'),
),
],
),
);
}
}
跳转页面完整代码如下,注意跳转的页面构造函数需要包含arguments
这个参数才可以:
import 'package:flutter/material.dart';
class JumpWithValuePage extends StatefulWidget {
var arguments;
///将需要的参数,直接传递过来
JumpWithValuePage({this.arguments=""}){
print(' JumpWithValuePage $arguments');
}
@override
_JumpPageState createState(){
print(' createState $arguments');
return _JumpPageState(arguments);
}
}
class _JumpPageState extends State<JumpWithValuePage> {
var value;
_JumpPageState(this.value);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('传入参数为 $value'),
),
body: Text('跳转页面'),
floatingActionButton: FloatingActionButton(
child: Text('返回'),
onPressed: (){
//返回
Navigator.of(context).pop(this);
},
),
);
}
}
三,路由替换
-
Navigator.of(context).pushReplacementNamed
这种场景适合替换路由:
根page--->A --> B每次点击返回,都返回的是 根page ,也就是说在跳转的时候,需要将上一个页面从栈中移除,也可以说替换掉,这时可以使用Navigator.of(context).pushReplacementNamed
在 A 跳转B页面 的使用,使用该方法进行跳转,此时在 B页面 点击返回会直接返回 根页面,不会在经过A
Navigator.of(context).pushReplacementNamed('/a');
-
Navigator.of(context).pushNamedAndRemoveUntil
:该方法会直接跳转到指定页面,并将其余所有页面出栈。
比如退出登录后,我只想保留登录页面,销毁其他页面,该方法就适用于这个场景:
// 注意,route == null 就是将之前的全部移出栈
Navigator.of(context).pushNamedAndRemoveUntil(
'/login',
(route) => route == null,
);
pushNamedAndRemoveUntil
两个参数,第一个是路由名'/login'
,第二个则是对堆栈中的 route 的处理:
route == null
清空了 route 全部置为 null,只会路由到 '/login'
这个页面。