文章已同步至掘金:https://juejin.cn/post/6844903950345306125
欢迎访问😃,有任何问题都可留言评论哦~
在 Flutter 中想要实现页面间的跳转和传值的话,离不开两种路由:
- 基本路由
- 命名式路由
官方说的是静态路由和动态路由,不过我习惯了这样叫,所以就暂且这样说吧!
基本路由
基本跳转
基本路由的跳转
使用push
跳到指定的页面,然后再使用pop
回到原来的页面
不过当你跳转过去的时候,人家默认会有一个返回的箭头按钮,点击就可以返回
开始撸代码
我在main.dart
文件中引用了Home.dart
文件
在Home.dart
文件中有一个按钮,当我点击的时候,可以跳到详情页面
注:如果用stl
生成的静态控件是不能用跳转按钮的
Home.dart
文件代码:
//Home.dart
import 'package:flutter/material.dart';
import './Detail.dart';
class Home extends StatefulWidget {
@override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: <Widget>[
RaisedButton(
child: Text('跳到详情页面'),
onPressed: (){
//跳转页面
Navigator.of(context).push(
MaterialPageRoute(
//没有传值
builder: (context)=>Detail()
)
);
},
)
],
),
);
}
}
当我点击了按钮的时候,就可以跳到详情页面:
Detail.dart
文件代码:
import 'package:flutter/material.dart';
class Detail extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
//浮动按钮
floatingActionButton: FloatingActionButton(
child: Text('返回'),
onPressed: (){
Navigator.of(context).pop();
},
),
appBar: AppBar(title: Text("详情页面"),),
body: Text("详情页面"),
);
}
}
如图,跳过去后默认会有一个返回按钮,点击后就可以返回 ,
也可以自己定义一个按钮,利用pop
方法点击后也可以返回
跳转传值
有时候我们跳转的时候需要传递参数,
这时候我们就要携带参数跳转,当然非常简单
我们需要在使用参数的页面定义一个变量,注意需要设置默认值,如果没给你传值的时候使用默认值
然后在跳转的时候给目标页面传值
Home.dart
文件代码:
//Home.dart
//只贴按钮的代码,其余的和上面一样
RaisedButton(
child: Text('跳到详情页面'),
onPressed: (){
//跳转页面
Navigator.of(context).push(
MaterialPageRoute(
//传值
builder: (context)=>Detail(Test:'我是参数')
//没传值
//builder: (context)=>Detail()
)
);
},
)
然后在目标页面接收,如果没传值默认为上面定义的默认值
Detail.dart
文件代码:
class Detail extends StatelessWidget {
//需要定义变量和默认值
String Test;
Detail({this.Test='没有给我传值'});
@override
Widget build(BuildContext context) {
return Scaffold(
//浮动按钮
floatingActionButton: FloatingActionButton(
child: Text('返回'),
onPressed: (){
Navigator.of(context).pop();
},
),
appBar: AppBar(title: Text("详情页面"),),
body: Text(this.Test),
);
}
}
返回时接收值
有时候我们跳转的时候不需要传值,而当你返回的时候需要从子组件中接收值
用下面这个例子来说明:
新建两个dart文件AddressList.dart
和GetAddress.dart
文件,在mian.dart
中使用GetAddress.dart
文件
我们想要点击GetAddress.dart
文件中的 选择收获地址 按钮,跳到添加地址页面,然后选择地址后,直接带着数据返回到首页面并显示出来
代码示例:
main.dart
文件只改了需要渲染的控件
import 'package:flutter/material.dart';
import './address/GetAddress.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("Route"),
),
body: GetAddress()
),
);
}
}
注意获取数据都是异步的,需要加async、await
改变数据的唯一方式是利用setState
方法
GetAddress.dart
文件代码:
import 'package:flutter/material.dart';
import './AddressList.dart';
class GetAddress extends StatefulWidget {
@override
_GetAddressState createState() => _GetAddressState();
}
class _GetAddressState extends State<GetAddress> {
//定义一个变量
String _ads = '';
@override
Widget build(BuildContext context) {
return Container(
child: Scaffold(
appBar: AppBar(title: Text('获取收获地址'),),
body: Center(
child: Column(
//垂直居中
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
RaisedButton(
//按钮主题
textTheme: ButtonTextTheme.primary,
color: Theme.of(context).accentColor,
child: Text('选择收货地址'),
//点击
onPressed: () async {
//通过路由跳转从子页面中传递过来的数据,都是异步的
var ads = await Navigator.of(context).push(
MaterialPageRoute(
builder: (BuildContext context){
return AddressList();
}
)
);
setState(() {
_ads = ads;
});
},
),
Text('${_ads==""?"未查到收货地址":_ads}')
],
),
),
),
);
}
}
利用onTap
点击后直接使用pop
返回到首页面,并把数据带回去
AddressList.dart
文件代码:
import 'package:flutter/material.dart';
class AddressList extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("我的地址列表"),),
body: ListView(
padding: EdgeInsets.all(10),
children: <Widget>[
GestureDetector(
onTap: (){
//pop后面可以跟上参数
Navigator.of(context).pop('北京');
},
//给子组件添加事件
child: Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.black26)
),
child: ListTile(
leading: Icon(
Icons.account_box,
color: Colors.blue,
),
title: Text(
'北京',
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
),
),
//给控件中间加间隙
SizedBox(height: 10),
GestureDetector(
onTap: (){
//pop后面可以跟上参数
Navigator.of(context).pop('河南');
},
//给子组件添加事件
child: Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.black26)
),
child: ListTile(
leading: Icon(
Icons.account_box,
color: Colors.blue,
),
title: Text(
'河南',
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
),
),
//给控件中间加间隙
SizedBox(height: 10),
GestureDetector(
onTap: (){
//pop后面可以跟上参数
Navigator.of(context).pop('上海');
},
//给子组件添加事件
child: Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.black26)
),
child: ListTile(
leading: Icon(
Icons.account_box,
color: Colors.blue,
),
title: Text(
'上海',
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
),
)
],
),
);
}
}
命名式路由
类似于 Vue 中的路由
基本跳转
新建了几个页面Main.dart
、Page1.dart
、Page1.dart
和Page3.dart
用来测试
引入文件,
在main.dart
中的routes
中配置路径(必须在main.dart中配置)
body
换成需要渲染的页面
main.dart
文件代码:
import 'package:flutter/material.dart';
import './files/Page1.dart';
import './files/Page2.dart';
import './files/Page3.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("Route"),
),
body: Main(),
),
//定义路由
routes: {
//需要使用context指定上下文
'/page1': (context) => Page1(),
'/page2': (context) => Page2(),
'/page3': (context) => Page3(),
},
);
}
}
在Main.dart
文件中写两个按钮用来跳转(注意一个是main.dart
一个是Main.dart
)
Main.dart
文件代码:
import 'package:flutter/material.dart';
class Main extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: Column(
children: <Widget>[
//定义按钮
RaisedButton(
child: Text("跳转到Page1"),
onPressed: () {
//需要使用pushNamed方法
Navigator.pushNamed(context, "/page1");
},
),
SizedBox(height: 20),
RaisedButton(
child: Text("跳转到Page2"),
onPressed: () {
Navigator.pushNamed(context, "/page2");
},
),
],
),
),
),
);
}
}
点击按钮跳转到指定页面,Page1.dart
、Page2.dart
、Page3.dart
页面的基本结构,只贴一个页面看一下:
Page1.dart
文件代码:
import 'package:flutter/material.dart';
class Page1 extends StatefulWidget {
@override
_Page1State createState() => _Page1State();
}
class _Page1State extends State<Page1> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Page1"),),
body: Text("Page1",style: TextStyle(fontSize: 40),),
);
}
}
路由抽离跳转
一般我们使用命名式路由的话,不用上面的方式,我们都是单独把路由抽离出去
优化上面的代码:
新建一个Routes.dart
文件用来存放路由规则,
Routes.dart
文件代码:
import 'package:flutter/material.dart';
//引入文件
import '../files/Main.dart';
import '../files//Page1.dart';
import '../files//Page2.dart';
import '../files//Page3.dart';
//配置路由规则
final routes = {
'/': (context) => Main(),
'/page1': (context) => Page1(),
'/page2': (context) => Page2(),
'/page3': (context) => Page3(),
};
// 如果你要把路由抽离出去,必须写下面这一堆的代码,不用理解什么意思
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;
}
}
};
然后在main.dart
文件中配置使用:
import 'package:flutter/material.dart';
//引入Routes.dart文件
import './routes/Routes.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
initialRoute: '/', //配置默认访问路径
onGenerateRoute:onGenerateRoute, //必须加上这一行,固定写法
);
}
}
配置好后,别的地方都不用动,这样就实现了我们的路由抽离
跳转传值
紧跟着上面的代码,当我们使用命名式路由,并且把路由抽离后进行跳转时,我们想要跳转过去的时候给他传值,那么怎么办呢?很简单
在上面代码的基础上改动
改变Main.dart
文件中的按钮方法,当跳转的时候传值,如下:
只粘贴第二个跳转按钮,别的代码不用动
RaisedButton(
child: Text("跳转到Page2"),
onPressed: () {
Navigator.pushNamed(context, "/page2",arguments: {
"id":102
});
},
),
然后在Routes.dart
文件中改变page2
路由规则:
'/page2': (context,{arguments}) => Page2(arguments:arguments),
最后在Page2.dart
页面定义变量,重构,接收传递过来的值:
import 'package:flutter/material.dart';
class Page2 extends StatefulWidget {
//定义一个变量
final arguments;
//重构
Page2({this.arguments});
@override
_Page2State createState() => _Page2State();
}
class _Page2State extends State<Page2> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Page2"),),
//使用传递过来的值
body: Text("${widget.arguments['id']}",style: TextStyle(fontSize: 40),),
);
}
}
源码
点击–>源码地址
评论区