flutter中的导航和路由
在flutter中,页面之间的跳转与数据传递使用的是Navigator.push和Navigator.pop,以及router。
1. 一般用法
1.1Navigator.push()
Navigator.push(BuildContext,Route< T > ),可以将点前的页面压入有Navigator管理的路由堆栈(stack of routes)中。
Navigitor.of(context).push(Route< T >)
Navigitor.of(context).push(MaterialPageRoute(builder: (context) {
return SecondPage();
}))
- 使用
Navigator.push(context, MaterialPageRoute(builder: (context) {
return SecondPage();
}));
- push 传的两个参数:
- context,默认的传入的,指向当前路由。
- Router 抽象方法需要实现的
MaterialPageRoute() // flutter内部提供的
//MaterialPageRoute({
// @required this.builder,
// RouteSettings settings,
// this.maintainState = true,
// bool fullscreenDialog = false,
// })
/// See [MaterialPageRoute] for a route that replaces the /// entirescreen with a platform-adaptive transition.
Material风格的进入页面过渡效果。
MaterialPageRoute(builder: (context) {
return SecondPage();
}
- 第一个页面
class FirstPage extends StatelessWidget {
void _navigateSecondPage(BuildContext context) {
//MaterialPageRoute({
// @required this.builder,
// RouteSettings settings,
// this.maintainState = true,
// bool fullscreenDialog = false,
// })
Navigator.push(context, MaterialPageRoute(builder: (context) {
return SecondPage();
}));
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Container(
child: RaisedButton( // 切换路由的按钮
child: Text("Navigator.push SecondsPages"),
onPressed: () { // 按钮被点击后触发的函数
_navigateSecondPage(context);
},
),
),
);
}
}
- 第二个页面SecondPage
class SecondPage extends StatelessWidget {
void _backCurrentPage(BuildContext context) { // 按钮点击触发的具体的函数
Navigator.pop(context); // 路由跳转,回到上一个页面
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Fisrt Page'),),
body: Container(
child: SafeArea( // 设置安全区域,解决右下角显示不全的问题
child: Container(
child: RaisedButton( // 切换路由的按钮
child: Text("Navigator.push FirstPages"),
onPressed: () {
_backCurrentPage(context);
},
),
),
),
),
);
}
}
1.2路由带参的写法
- 对 SecondPage的改造
class SecondPage extends StatelessWidget {
+ final value;
+ SecondPage({Key:key,@require this.value});
void _backCurrentPage(BuildContext context) { // 按钮点击触发的具体的函数
Navigator.pop(context); // 路由跳转,回到上一个页面
}
@override
Widget build(BuildContext context) {
return Scaffold(
- appBar: AppBar(title: Text('Fisrt Page'),),
+ appBar: AppBar(title: Text("$value"),),
body: Container(
child: SafeArea( // 设置安全区域,解决右下角显示不全的问题
child: Container(
child: RaisedButton( // 切换路由的按钮
child: Text("Navigator.push FirstPages"),
onPressed: () {
_backCurrentPage(context);
},
),
),
),
),
);
}
}
- 对 FirstPage的改造
class FirstPage extends StatelessWidget {
void _navigateSecondPage(BuildContext context) {
//MaterialPageRoute({
// @required this.builder,
// RouteSettings settings,
// this.maintainState = true,
// bool fullscreenDialog = false,
// })
Navigator.push(context, MaterialPageRoute(builder: (context) {
- return SecondPage();
+ return SecondPage(value:'我是FirstPage也带来的数据');
}));
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Container(
child: RaisedButton( // 切换路由的按钮
child: Text("Navigator.push SecondsPages"),
onPressed: () { // 按钮被点击后触发的函数
- _navigateSecondPage(context);
},
),
),
);
}
}
就此完成了路由传参了。
2.与对应的页面对应起来的,进行命名路由的跳转。
import 'package:flutter/material.dart';
// 对页面路由进行一个统一的管理
class NamedRouter {
static Map<String, WidgetBuilder> routes;
//初始化App
static Widget initApp() {
return MaterialApp(
initialRoute: '/',
routes: NamedRouter.initRoutes(),
);
}
//初始化路由
static initRoutes() {
routes = {
'/': (context) => FirstScreen(),
'/second': (context) => SecondScreen()
};
return routes;
}
}
class FirstScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('First Screen'),
),
body: Center(
child: RaisedButton(
child: Text('Launch screen'),
onPressed: () {
// Navigate to the second screen using a named route
** Navigator.pushNamed(context, '/second');// 这里调用了push.Named()的这个方法
},
),
),
);
}
}
class SecondScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Second Screen"),
),
body: Center(
child: RaisedButton(
onPressed: () {
// Navigate back to the first screen by popping the current route
// off the stack
Navigator.pop(context);
},
child: Text('Go back!'),
),
),
);
}
}
//main函数中使用
void main() => runApp(NamedRouter.initApp());
- push.Named() 的使用,传入context和路由名
Navigator.pushNamed(context, ‘/second’);