Flutter 路由练习之 命名路由跳转,带参数跳转,抽离单独路由,替换路由,返回跟路由
2019/12/31 8:57:59 | 阅2695 | 来源:好空间网络 [打印] [关闭] |
1:命名路由跳转
主要是这里:
//在MaterialApp里面有个routes的方法,在这里定义命名路由
//前面是名称,后面是小部件的方法名,注意需要在顶部引入这个文件
routes: {
'/test':(context)=>TestPage(),
},
和这里:
//在这里字节pushName(上下文,命名路由名称即可)
Navigator.pushNamed(context,"/test");
import 'package:flutter/material.dart'; import 'TestPage.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { // TODO: implement build return MaterialApp( title: "多窗口切换标题", home: Scaffold( appBar: AppBar( title: Text("命名路由练习"), ), body: MyRoute(), ), //在MaterialApp里面有个routes的方法,在这里定义命名路由 //前面是名称,后面是小部件的方法名,注意需要在顶部引入这个文件 routes: { '/test':(context)=>TestPage(), }, ); } } class MyRoute extends StatelessWidget { const MyRoute({Key key}) : super(key: key); @override Widget build(BuildContext context) { return Container( child: FlatButton( child: Text("命名路由跳转"), onPressed: (){ //在这里字节pushName(上下文,命名路由名称即可) Navigator.pushNamed(context,"/test"); }, ), ); } }
效果图:
2:命名路由的传值,代码里有详细的注解,每个步骤我都有标明,注意是2个文件一起联合的哟
import 'package:flutter/material.dart'; //1:引入需要跳转的路由页面 import 'TestPage.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { //2:命名路由先定义路由列表 final routes= { //4:配置要跳转的参数,是个可选的,记得在跳转页面要做接收处理,要不然这里的会报错的 '/test':(context,{arguments})=>TestPage(arguments:arguments), }; @override Widget build(BuildContext context) { // TODO: implement build return MaterialApp( title: "多窗口切换标题", home: Scaffold( appBar: AppBar( title: Text("命名路由练习"), ), body: MyRoute(), ), //3:在MaterialApp里面不要在监听routes的方法,而是监听onGenerateRoute方法 onGenerateRoute:(RouteSettings settings){ //获得路由名称 final String name = settings.name; //获得路由的值 final Function pageContentBuilder= this.routes[name]; //如果路由值不为空 if(pageContentBuilder != null){ //如果要跳转的参数不为空 if(settings.arguments != null){ //定义一个路由,实现build方法,把参数带进去,然后返回该路由 final Route route = MaterialPageRoute( builder: (context)=> pageContentBuilder(context, arguments:settings.arguments) ); return route; }else{ //没有带参数,字节返回路由 final Route route = MaterialPageRoute(builder: (context)=> pageContentBuilder(context)); return route; } } } , ); } } class MyRoute extends StatelessWidget { const MyRoute({Key key}) : super(key: key); @override Widget build(BuildContext context) { return Container( child: FlatButton( child: Text("命名路由跳转"), onPressed: (){ //6:在这里字节pushName(上下文,命名路由名称,参数arguments:{键值对}) Navigator.pushNamed(context,"/test",arguments:{ "id":1232,"name":"命名路由", }); }, ), ); } }
2.1:接收的页面
import 'package:flutter/material.dart'; class TestPage extends StatelessWidget { final arguments; //5:构造函数里面接收一个arguments 可选的 TestPage({this.arguments}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("测试路由一个新页面"), ), body: Column( children: <Widget>[ //7:接收和打印传递的值 Text("这个是一个名称为: ${arguments['name']} 传递过来的值 ID:${arguments['id']}"), FlatButton( child: Text("返回"), onPressed:(){ //返回上一页 Navigator.of(context).pop(); } , ) ], ) ); } }
效果图: 传递了一个name="命名路由",id=1232 的值
3:把命名路由单独抽取出来,这样方便以后管理,每个步骤也写好了不在解释
3.1:新建routes/Route.dart路由文件
// 配置集中路由 import 'package:flutter/material.dart'; //1:引入需要跳转的路由页面 import '../TestPage.dart'; import '../HomePage.dart'; //2:命名路由先定义路由列表 final routes = { //4:配置要跳转的参数,是个可选的,记得在跳转页面要做接收处理,要不然这里的会报错的 '/':(context)=>home(), //根路由不用传值 HomePage.dart 文件暴露的方法 '/test': (context, {arguments}) => TestPage(arguments: arguments),//要传值的写法 }; //3:在MaterialApp里面不要在监听routes的方法,而是监听onGenerateRoute方法 var onGenerateRoute = (RouteSettings settings) { //获得路由名称 final String name = settings.name; //获得路由的值 final Function pageContentBuilder = routes[name]; //如果路由值不为空 if (pageContentBuilder != null) { //如果要跳转的参数不为空 if (settings.arguments != null) { //定义一个路由,实现build方法,把参数带进去,然后返回该路由 final Route route = MaterialPageRoute( builder: (context) => pageContentBuilder(context, arguments: settings.arguments)); return route; } else { //没有带参数,字节返回路由 final Route route = MaterialPageRoute(builder: (context) => pageContentBuilder(context)); return route; } } };
3.2:新建HomePage.dart 主页文件 ,因为路由统一独立管理了,所以主页也放到路由里面管理
//主页文件 import 'package:flutter/material.dart'; class home extends StatelessWidget { const home({Key key}) : super(key: key); @override Widget build(BuildContext context) { return Container( child: Scaffold( appBar: AppBar( title: Text("命名路由练习"), ), body: MyRoute(), ), ); } } class MyRoute extends StatelessWidget { const MyRoute({Key key}) : super(key: key); @override Widget build(BuildContext context) { return Container( child: FlatButton( child: Text("命名路由跳转"), onPressed: (){ //6在这里直接跳转 pushName(上下文,命名路由名称,参数arguments:{键值对}) Navigator.pushNamed(context,"/test",arguments:{ "id":1232,"name":"命名路由", }); }, ), ); } }
3.3:修改main.dart主入口文件
import 'package:flutter/material.dart'; import 'routes/Routes.dart'; import 'HomePage.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: "多窗口切换标题", //9:由于入口文件被单独抽离为homepage.dart了,并且在独立路由里面配置了,所以设置下默认路由 initialRoute: '/', //7:调用Routes.dart的路由方法 onGenerateRoute: onGenerateRoute, ); } }
3.4增加testpage.dart文件,这个文件和明明路由里面的几乎没有修改只是修改了备注里面的步骤
import 'package:flutter/material.dart'; class TestPage extends StatelessWidget { final arguments; //5:构造函数里面接收一个arguments 可选的 TestPage({this.arguments}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("测试路由一个新页面"), ), body: Column( children: <Widget>[ //8:接收和打印传递的值 Text("这个是一个名称为: ${arguments['name']} 传递过来的值 ID:${arguments['id']}"), FlatButton( child: Text("返回"), onPressed:(){ //返回上一页 Navigator.of(context).pop(); } , ) ], ) ); } }
效果图:
4:的动态widget获取传值
//本文件演示 命名路由 如何在 statefulWidget下使用 import 'package:flutter/material.dart'; class ProductInfoPage extends StatefulWidget { //1:接收传递的值 Map arguments; //2:构造函数赋值 ProductInfoPage({this.arguments}); @override //3:把传输传递到state具体实现widget里 _ProductInfoPageState createState() => _ProductInfoPageState(arguments:this.arguments); } class _ProductInfoPageState extends State<ProductInfoPage> { //4:定义一个接收参数的变量 Map arguments; //5:构造函数接收这个参数 _ProductInfoPageState({this.arguments}); @override Widget build(BuildContext context) { return Scaffold(//因为是个独立页面所以需要加个scaffold appBar: AppBar( title: Text("动态Widget 获取传值"), ), body: Container( //6:接收值 child: Text("动态Widget 获得命名路由传值 名称:${arguments['name']} id:${arguments['id']}"), ), ); } }
5:替换路由
Navigator.of(context).pushReplacementNamed('/login');
用login的页面替换当前的路由页面,这样当用户在点返回就可以返回主页了,注意这个好像只适合第三页替换第二页的,因为替换了第二页用户在点返回才能返回主页,如果有第四或者第五页好像要一直替换才可以
6:返回根路由: new ProuuctInfoPage() 为要返回的根路径
Navigator.of(context).pushAndRemoveUntil( new MaterialPageRoute(builder: (context) => new ProductInfoPage()), (route) => route == null);