本文对应github地址Flutter11,若是因为github调整致使资源找不到,请访问githubgit
路由
简介github
静态路由pushbash
// MaterialApp初始化时配置Key-Value
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primaryColor: Colors.red,
primarySwatch: Colors.blue,
),
home: DDYBottomBar(),
showPerformanceOverlay: false,
routes: {
'/home/qrcode': (BuildContext context) => QRCodeScanner(title: '0',),
'/home_qrcode': (BuildContext context) => QRCodeScanner(title: '1',),
'+home_qrcode': (BuildContext context) => QRCodeScanner(title: '2',),
},
);
}
}
// 在须要的地方调用['/home/qrcode'只是字符串名字,并非真正路径,这样仿路径是为了可读性]
// Navigator.pushNamed(context, '/home/qrcode');
// Navigator.pushNamed(context, '/home_qrcode');
// Navigator.pushNamed(context, '+home_qrcode');
Navigator.of(context).pushNamed('+home_qrcode');
复制代码
动态路由push闭包
// Navigator.push(context, MaterialPageRoute(builder: (context) => QRCodeScanner()));
// Navigator.of(context).push(MaterialPageRoute(builder: (_) => QRCodeScanner()));
Navigator.of(context).push(MaterialPageRoute(builder: (context) => QRCodeScanner()));
复制代码
路由popless
// Navigator.of(context).pop();
// Navigator.pop(context);
Navigator.of(context).pop('回调数据');
复制代码
页面传值异步
正向传值直接经过简单构造函数参数方式便可async
反向传值,不一样风格其实都同样,建议第一种ide
// 风格1
pushQRCodeScannerAndCallbackData1() {
Navigator.of(context).push(MaterialPageRoute(builder: (context) => QRCodeScanner())).then((value){
print('1 $value');
});
}
// 风格2
pushQRCodeScannerAndCallbackData2() {
Future callbackFuture = Navigator.of(context).push(MaterialPageRoute(builder: (_) => QRCodeScanner()));
callbackFuture.then((value){
print('2 $value');
});
}
// 风格3
pushQRCodeScannerAndCallbackData3() async {
// 若是知道类型
String callbackString = await Navigator.of(context).push<String>(
MaterialPageRoute(builder: (context){
// 正向传值直接经过简单构造函数参数方式便可
return QRCodeScanner(title:'I am 3');
})
);
if (callbackString != null) {
print('3 ${callbackString}');
}
}
// pop()函数参数值即为反向传回的数据
Navigator.of(context).pop('回调数据');
复制代码
还能够经过闭包做为参数进行传值函数
pushQRCodeGenerator() {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => QRCodeGenerator((String value) {
print('QRCodeGenerator callback $value');
}),
),
);
}
// 调用
IconButton(
icon: Icon(Icons.print),
onPressed: () {
if (widget.callbackFunction != null) {
widget.callbackFunction('回调数据');
}
},
),
复制代码
继承路由子类,如:PopupRoute、ModalRoute 等ui
使用 PageRouteBuilder 类经过回调函数定义路由
pushQRCodeScannerWithCustomAnimation() {
Navigator.push(
context,
PageRouteBuilder(pageBuilder: (BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) {
return QRCodeScanner();
}, transitionsBuilder: (context, animation, secondaryAnimation, child) {
return transitionAnimation(animation, child);
}),
);
}
static SlideTransition transitionAnimation(Animation<double> animation, Widget child) {
return SlideTransition(
position: Tween<Offset>(
begin: const Offset(0.0, 1.0),
end: const Offset(0.0, 0.0),
).animate(animation),
child: child,
);
}
复制代码
pushQRCodeScannerWithCustomAnimation2() async {
// 页面旋转淡出的效果
transitionAnimation(Animation<double> animation, Widget child) {
return FadeTransition(
opacity: animation,
child: RotationTransition(
turns: Tween<double>(begin: 0.7, end:1.0).animate(animation),
child: child,
),
);
}
Navigator.push(
context,
PageRouteBuilder(
pageBuilder: (context, _, __) => QRCodeScanner(),
transitionDuration: const Duration(milliseconds: 1000),
transitionsBuilder: (_, animation, __, child) => transitionAnimation(animation, child),
),
).then((value){
Scaffold.of(context).showSnackBar(
SnackBar(
content: Text(value),
duration: const Duration(seconds: 3),
),
);
});
}
复制代码
一个应用程序可使用多个路由导航器
可将一个导航器嵌套在另外一个导航器下方使用,例如选项卡式导航,用户注册,订单与结帐页等
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
initialRoute: '/',
routes: {
'/': (BuildContext context) => HomePage(),
'/signup': (BuildContext context) => SignUpPage(),
},
);
}
}
class SignUpPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Navigator(
initialRoute: 'signup/personal_info',
onGenerateRoute: (RouteSettings settings) {
WidgetBuilder builder;
switch (settings.name) {
case 'signup/personal_info':
// 我的信息完毕后到 'signup/choose_credentials'.
builder = (BuildContext _) => CollectPersonalInfoPage();
break;
case 'signup/choose_credentials':
// 选完credentials 调用 'onSignupComplete()'.
builder = (BuildContext _) => ChooseCredentialsPage(
onSignupComplete: () {
// 回到路由根页面 '/' (HomePage)
Navigator.of(context).pop();
},
);
break;
default:
throw Exception('Invalid route: ${settings.name}');
}
return MaterialPageRoute(builder: builder, settings: settings);
},
);
}
}
复制代码
Navigator
pushName结合配置routes,利用命名路由形式将指定页面实例(带固定参数)入栈,而push则是在须要跳转时生成要跳转的页面对象,传递想要的参数,二者运行效果没差异。
二者都是取代栈顶元素,运行效果没差异。
顾名思义,先pop而后push
二者都是入栈新页面删除除该页面实例外其余栈内实例,将该实例做为新栈底,运行效果没差异。可用在注册登陆页登陆后跳转,防止能返回注册登陆页
判断是否能够pop,若是能够返回true,不然返回false
表示在该页面尝试pop,若是能够则pop到前一页,不然仍停在该页面,丢弃该次pop
pop回栈内(该页面实例如下)指定页面实例,如 Navigator.popUntil(context, ModalRoute.withName('/home'));
,回到配置名为home的页面。
其余知识点
去除返回按钮 AppBar中
automaticalImplyLeading: false
复制代码
Popup routes (弹出路由)
路由不必定要遮挡整个屏幕。 PopupRoutes 使用 ModalRoute.barrierColor 覆盖屏幕,ModalRoute.barrierColor 只能部分不透明以容许当前屏幕显示。 弹出路由是“模态”的,由于它们阻止了对下面其余组件的输入。
有一些方法能够建立和显示这类弹出路由。 例如:showDialog,showMenu 和 showModalBottomSheet。 如上所述,这些函数返回其推送路由的 Future(异步数据,参考下面的数据部分)。 执行能够等待返回的值在弹出路由时执行操做。
还有一些组件能够建立弹出路由,如 PopupMenuButton 和 DropdownButton。 这些组件建立 PopupRoute 的内部子类,并使用 Navigator 的push 和 pop 方法来显示和关闭它们。
参考
上一页 Flutter10 Icon、Color、Tabbar、BottomNavigationBar
下一页 Flutter12 ListBody、ListView、ListTile