当前位置:   article > 正文

flutter如何引用传值_Flutter 路由跳转及传值详解(Navigator的使用)

flutter 传引用

在 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 {

@override

Widget build(BuildContext context) {

return Scaffold(

body: Column(

children: [

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方法点击后也可以返回

cfbc722406047e2d28d37a8d92a7e4ee.png

跳转传值

有时候我们跳转的时候需要传递参数,

这时候我们就要携带参数跳转,当然非常简单

我们需要在使用参数的页面定义一个变量,注意需要设置默认值,如果没给你传值的时候使用默认值

然后在跳转的时候给目标页面传值

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),

);

}

}

复制代码

0301427ae32d249e58704c733e27b21e.png

返回时接收值

有时候我们跳转的时候不需要传值,而当你返回的时候需要从子组件中接收值

用下面这个例子来说明:

新建两个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 {

//定义一个变量

String _ads = '';

@override

Widget build(BuildContext context) {

return Container(

child: Scaffold(

appBar: AppBar(title: Text('获取收获地址'),),

body: Center(

child: Column(

//垂直居中

mainAxisAlignment: MainAxisAlignment.center,

children: [

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: [

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,

),

),

),

)

],

),

);

}

}

复制代码

3230d2373a00d039f72d70db99e3d5d6.png

命名式路由

类似于 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: [

//定义按钮

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 {

@override

Widget build(BuildContext context) {

return Scaffold(

appBar: AppBar(title: Text("Page1"),),

body: Text("Page1",style: TextStyle(fontSize: 40),),

);

}

}

复制代码

0622cf79ea264ed84db539f2f8afd582.png

路由抽离跳转

一般我们使用命名式路由的话,不用上面的方式,我们都是单独把路由抽离出去

优化上面的代码:

新建一个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 {

@override

Widget build(BuildContext context) {

return Scaffold(

appBar: AppBar(title: Text("Page2"),),

//使用传递过来的值

body: Text("${widget.arguments['id']}",style: TextStyle(fontSize: 40),),

);

}

}

复制代码

12369d14a15b31869eae6556f4f5dae9.png

源码

点击-->源码地址

@_@

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/在线问答5/article/detail/995741
推荐阅读
相关标签
  

闽ICP备14008679号