Flutter 关于路由跳转:
关于flutter项目中的路由跳转
1. 普通路由跳转和传值
在当前页面引入需要跳转的页面组件,通过Navigator.of(context).push()进行路由跳转;Navigator.of(context).pop()返回上一页面。
// Home.dart
RaisedButton(
child: Text("点击跳转到搜索页面"),
onPressed: (() {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => SearchPage(
// 传递title参数
title: "这里是传入标题",
)));
}))
// Seach.dart
import 'package:flutter/material.dart';
class SearchPage extends StatelessWidget {
// 定义title,接收参数
String title;
SearchPage({this.title = "默认标题"});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(this.title),
),
body: Container(
padding: EdgeInsets.all(20),
child: Text(
"欢迎来到搜索页面",
style: TextStyle(fontSize: 25.0, color: Colors.red),
),
),
// 浮动按钮
floatingActionButton: FloatingActionButton(
child: Text("返回"),
onPressed: () {
// 返回上一页面
Navigator.of(context).pop();
},
),
);
}
}
2. 命名路由
使用命名路由,首先需要在main.dart里面配置路由。路由跳转,使用 Navigator.pushNamed(context, routeName)。
// main.dart
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
// 初始化的时候加载的路由
initialRoute: '/',
// 命名路由
routes: {
'/':(contxt)=>Tabs(),
'/form': (context) => Forms(),
'/search': (context) => SearchPage()
},
);
}
}
// 需要跳转的文件里面
RaisedButton(
child: Text("点击跳转到搜索页面"),
onPressed: (() {
Navigator.pushNamed(context, '/search');
}))
这里需要注意,命名路由就不能直接传值了,官方文档有给出一个命名路由的传值示例,可以进行参考:https://flutter.dev/docs/cookbook/navigation/navigate-with-arguments
3. 命名路由跳转传值
这里可以将所有的路由处理部分,抽取为单独的一个文件route.dart,在main文件中进行调用。
import 'package:flutter/material.dart';
import '../pages/Tabs.dart';
import '../pages/Search.dart';
// 配置路由
final routes = {
'/': (context) => Tabs(),
// 传递arguments参数
'/search': (context, {arguments}) => SearchPage(arguments: arguments),
};
// 固定方法
var onGenerateRoute = (RouteSettings settings) {
// 统一处理 命名路由传参
final String name = settings.name;
final Function pageContentBuilder = routes[name];
if (pageContentBuilder != null) {
if (settings.arguments != null) {
final Route route = MaterialPageRoute(
builder: (context) =>
pageContentBuilder(context, arguments: settings.arguments));
return route;
} else {
final Route route =
MaterialPageRoute(builder: (context) => pageContentBuilder(context));
return route;
}
}
};
// 跳转路由处进行传参,传一个id为990
RaisedButton(
child: Text("点击跳转到搜索页面"),
onPressed: (() {
Navigator.pushNamed(context, '/search', arguments: {"id": 990});
}))
我们可以在SearchPage 里面接收arguments参数
class SearchPage extends StatelessWidget {
final arguments;
SearchPage({this.arguments});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("标题"),
),
body: Container(
padding: EdgeInsets.all(20),
child: Text(
"欢迎来到搜索页面${arguments != null ? arguments['id'] : '0'}",
style: TextStyle(fontSize: 25.0, color: Colors.red),
),
),
);
}
}
4. Flutter 中替换路由
我们从用户中心页面跳转到了 First 页面,然后从 First 页面通过pushReplacementNamed 跳转到了 Second 页面。这个时候当我们点击Second的返回按钮的时候它会直接返回到用户中心,如果这里使用路由跳转Navigator.pushNamed,返回只能返回 First 页面。路由依旧写在route文件中,同上所述,这里只展示关键代码。
// First.dart
RaisedButton(
child: Text( "下一页",style: TextStyle(fontSize: 24.0)),
onPressed: () {
// 替换路由 这样直接在下一页可以使用pop()返回
Navigator.of(context).pushReplacementNamed('/second');
},
)
// Second.dart
RaisedButton(
child: Text("完成",style: TextStyle(fontSize: 24.0)),
onPressed: () {
Navigator.of(context).pop();
},
)
5. 返回根路由
这里也可以直接跳转回跟路由,实现与第4点中相同的效果。
RaisedButton(
child: Text("完成",style: TextStyle(fontSize: 24.0)),
onPressed: () {
// 返回根路由
Navigator.of(context).pushAndRemoveUntil(
new MaterialPageRoute(
builder: (context) => Tabs(
index: 3,
)),
(route) => route == null);
},
)
在这里tabs传参是因为我是在底部tab中第四个tab的页面中写的跳转,但是返回tab页默认会进入第一个tab页,这里传参为3,让currentIndex值为3,返回我们跳转之前的页面。