在 Flutter 中,页面之间的跳转是通过 Route 和 Navigator 来管理的:
Route 是页面的抽象,主要负责创建对应的界面,接收参数,响应 Navigator 打开和关闭;而 Navigator 则会维护一个路由栈管理 Route,Route 打开即入栈,Route 关闭即出栈,还可以直接替换栈内的某一个 Route。
基本路由:无需提前注册,在页面切换时需要自己构造页面实例。
class FirstScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return RaisedButton(
// 打开页面
onPressed: ()=> Navigator.push(context, MaterialPageRoute(builder: (context) => SecondScreen()));
);
}
}
class SecondPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return RaisedButton(
// 回退页面
onPressed: ()=> Navigator.pop(context)
);
}
}
传值
class RouterTestRoute extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child:ElevatedButton(
onPressed: ()async {
// 打开`TipRoute`,并等待返回结果
var result =await Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return TipRoute(
// 路由参数
text:"我是提示xxxx",
);
},
),
);
//输出`TipRoute`路由返回结果
print("路由返回值: $result");
},
child:Text("打开提示页"),
),
);
}
}
class TipRoute extends StatelessWidget {
TipRoute({
Key? key,
required this.text,// 接收一个text参数
}) :super(key: key);
final String text;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar:AppBar(
title:Text("提示"),
),
body:Padding(
padding:EdgeInsets.all(18),
child:Center(
child:Column(
children: [
Text(text),
ElevatedButton(
onPressed: () =>Navigator.pop(context,"我是返回值"),
child:Text("返回"),
)
],
),
),
),
);
}
}
命名路由:需要提前注册页面标识符,在页面切换时通过标识符直接打开新的路由。
class MyApp20 extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title:'Navigation',
//路由表
routes:{
"second_page":(context)=>SecondPage(),
"third_page":(context)=>ThirdPage()
},
//路由异常页面
onUnknownRoute: (RouteSettings setting) =>MaterialPageRoute(builder: (context) =>UnknownPage()),
home:FirstPage(),
);
}
}
class FirstPage extends StatefulWidget
{
@override
StatecreateState() =>_FirstPageState();
}
class _FirstPageState extends State {
String _msg='';
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar:new AppBar(
title:new Text('First Screen'),
),
body:Column(children: [
RaisedButton(
child:Text('命名路由'),
onPressed: ()=>Navigator.pushNamed(context,"second_page")
),
RaisedButton(
child:Text('命名路由(参数&回调)'),
onPressed: ()=>Navigator.pushNamed(context,"third_page",arguments:"Hey123").then((msg) {
setState(() {
_msg = msgas String;
});
}),
),
Text('Message from Second screen: $_msg'),
RaisedButton(
child:Text('命名路由异常处理'),
onPressed: ()=>Navigator.pushNamed(context,"unknown_page")
)
],),
);
}
}
class SecondPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar:new AppBar(
title:new Text('Second Screen'),
),
body:RaisedButton(
child:Text('Back to first screen'),
onPressed: ()=>Navigator.pop(context)
),
);
}
}
class ThirdPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
String msg =ModalRoute.of(context)?.settings.arguments as String;
return Scaffold(
appBar:AppBar(
title:Text('Third Screen'),
),
body:Column(
children: [
Text('Message from first screen: $msg'),
RaisedButton(
child:Text('back'),
onPressed: ()=>Navigator.pop(context,"Hi123")
)
],
),
);
}
}
class UnknownPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar:new AppBar(
title:new Text('Unknown Screen'),
),
body:RaisedButton(
child:Text('Back'),
onPressed: ()=>Navigator.pop(context)
),
);
}
}
网友评论