https://blog.csdn.net/senkai123/article/details/102948524
Flutter 命名路由、路由组、路由退出、路由堆栈
在flutter中需要进行页面跳转,也是需要用到路由Route,关键Navigator与Route,Navigator负责单元Route路由,压入和弹出,单元路由也就是我们需要跳转页面 ,比如HomePage()
Navigator关键使用的4个属性
•initialRoute: 初始路由的,也就是进入APP,默认页面
•onGenerateRoute: 路由拦截器
•onUnknownRoute: 找不到页面,也就是404
•routes : 路由集合,也就在执行路由跳转的时候,会到路由集合里面的子路由进行匹配,如果匹配 到那么就调整到指定页面
路由跳转 方式:
1.通过路由名打开新路由页面
通过路由名称来打开新路由,可以使用Navigator 的pushNamed方法:
Future pushNamed(BuildContext context, String routeName,{Object arguments})
1
调用:
onPressed: () {
//不带参数
Navigator.pushNamed(context, "new_page");
//带参数,可以指定单个参数,或者多个, arguments: {}
Navigator.of(context).pushNamed("new_page", arguments: "hi");
},
页面承接带过来的参数
String tmp = ModalRoute.of(context).settings.arguments.toString();
1
2.匿名路由打开新路由页面
Navigator.push( context, MaterialPageRoute(builder: (context) {
return HomePage();
}));
传参:
final Map<String, WidgetBuilder> _routes = {
'/sign': (context, {arguments}) => SignPage(arguments: arguments),
};
接参:
class SignPage extends StatelessWidget {
final Map arguments;
SignPage({Key key, this.arguments}) : super(key: key) {
}
@override
Widget build(BuildContext context) {
String tmp2 = this.arguments.toString();
}
}
路由集合(路由表)与onGenerateRoute的关系
onGenerateRoute接受一个 Route 工厂函数
final RouteFactory onGenerateRoute;
1
路由拦截源码,从拦截到路由之后,首先从路由表中拿到路由的 builder,如果能够拿到 builder,则判断是否存在 RouteSettings,如果存在则直接通关构造函数的 arguments 传递给页面 Page Widget。本质就是按照路由名字匹配路由表,然后跳转到正确页面中
Route _routeGenerator(RouteSettings settings) {
final String name = settings.name;
final Function pageBuilder = this._routes[name];
if (pageBuilder != null) {
if (settings.arguments != null) {
// 如果透传了参数
return MaterialPageRoute(
builder: (context) =>
pageBuilder(context, arguments: settings.arguments));
} else {
// 没有透传参数
return MaterialPageRoute(builder: (context) => pageBuilder(context));
}
}
return MaterialPageRoute(builder: (context) => HomeContent());
}
路由的使用方式
第一个种,初始化执行路线,initialRoute -> onGenerateRoute -> onUnknownRoute, 路由跳转Navigator.pushNamed(context, “secondPage”); ,之后会到onGenerateRoute ,进行路由拦截匹配,如果能正确匹配到,那么跳转到指定页面
例子:
import 'package:flutter/material.dart';
class NavigatorPage extends StatefulWidget {
@override
_NavigatorPageState createState() => _NavigatorPageState();
}
class _NavigatorPageState extends State<NavigatorPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Navigator'),
),
body: Column(
children: <Widget>[
Text('Navigator的高度为infinity'),
Text('如果直接父级非最上级也是infinity会产生异常'),
Container(
height: 333,
color: Colors.amber.withAlpha(111),
child: Navigator( // Navigator
initialRoute: '/abc',
onGenerateRoute: (val) {
RoutePageBuilder builder;
switch (val.name) {
case '/abc':
builder = (BuildContext nContext, Animation<double> animation, Animation<double> secondaryAnimation) => Column(
// 并没有在 MaterialApp 中设定 /efg 路由
// 因为Navigator的特性 使用nContext 可以跳转 /efg
children: <Widget>[
Text('呵呵呵'),
RaisedButton(
child: Text('去 /efg'),
onPressed: () {
Navigator.pushNamed(nContext, '/efg');
},
)
],
);
break;
case '/efg':
builder = (BuildContext nContext, Animation<double> animation, Animation<double> secondaryAnimation) => Row(
children: <Widget>[
RaisedButton(
child: Text('去 /hhh'),
onPressed: () {
Navigator.pushNamed(nContext, '/hhh');
},
)
],
);
break;
default:
builder = (BuildContext nContext, Animation<double> animation, Animation<double> secondaryAnimation) => Center(
child: RaisedButton(
child: Text('去 /abc'),
onPressed: () {
Navigator.pushNamed(nContext, '/abc');
},
)
);
}
return PageRouteBuilder(
pageBuilder: builder,
// transitionDuration: const Duration(milliseconds: 0),
);
},
onUnknownRoute: (val) {
print(val);
},
observers: <NavigatorObserver>[]
),
),
Text('Navigator执行寻找路由顺序'),
Text('initialRoute'),
Text('onGenerateRoute'),
Text('onUnknownRoute'),
],
),
);
}
}
第二个种,初始化执行路线,routes ->onUnknownRoute,路由跳转Navigator.pushNamed(context, “secondPage”);,之后会到routes 路由集合之后,能匹配到正确的路由子路由,那么就跳转到子路由中
例子:
import 'package:flutter/material.dart';
import 'package:flutter_routes/errorpage.dart';
import 'package:flutter_routes/homepage.dart';
import 'package:flutter_routes/navigator_with_result.dart';
import 'package:flutter_routes/page1.dart';
import 'package:flutter_routes/page2.dart';
import 'package:flutter_routes/page3.dart';
import 'package:flutter_routes/page4.dart';
import 'package:flutter_routes/page5.dart';
import 'package:flutter_routes/pageroutebuilderresult.dart';
import 'package:flutter_routes/splash.dart';
import 'package:flutter_routes/testpageroutebuilder.dart';
import 'package:flutter_routes/todo.dart';
import 'package:flutter_routes/welcome.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter路由',
theme: ThemeData(
primarySwatch: Colors.blue,
),
// 路由集合
routes: {
'/page1': (context) => Page1(),
'/page2': (context) => Page2(),
'/page3': (context) => Page3(),
'/page4': (context) => Page4(),
'/page5': (context) => Page5(),
'/todo': (context) => TodosScreen(),
'/splash': (context) => Splash(),
'/welcome': (context) => Welcome(),
'/homepage': (context) => HomePage(),
'/PageRouteBuilder': (context) => TestPageRouteBuilder(),
'/PageRouteBuilderResult': (context) => PageRouteBuilderResult(),
},
// 找不到路由,显示的错误页面
onUnknownRoute: (RouteSettings setting) {
String name = setting.name;
print("未匹配到路由:$name");
return new MaterialPageRoute(builder: (context) {
return new ErrorPage();
});
},
home: Page1(),
);
}
}
Page1 页面
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
class Page1 extends StatelessWidget {
Page1({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('page1'),
),
body: Center(
child: RaisedButton(
child: Text('跳转到Page2'),
onPressed: () {
// 路由跳转
Navigator.pushNamed(context, '/page2');
},
),
),
);
}
}
在实际开发过程中,建议用命名路由方式来跳转新的页面,便于维护,开发项目
路由堆栈的使用方式
1、在用这种方式路由跳转新页面的时候,是把页面放在堆栈里面,这个栈的特性就是,先进后出, Navigator.push 或者 pushNamed 实现的,每次都是把页面压入堆栈,在回退 的时候会回退到上一跳页面
Navigator.of(context).pushNamed('/search');
1
2.如果需要清空堆栈,比如我需要直接返回首页,之前的所有路由全部干掉,堆栈清空
Navigator.of(context).pushNamedAndRemoveUntil
1
页面退出堆栈
Navigator.pop(context, "我是返回值"),
1
参考文章
https://blog.csdn.net/weixin_30512027/article/details/85334391
https://blog.csdn.net/weixin_34999505/article/details/86760606
————————————————
版权声明:本文为CSDN博主「逐流间隔年」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/senkai123/java/article/details/102948524