Flutter 如何在切换页面的时候,把参数传到下一个页面?

时间: 2019-09-08阅读: 48标签: 路由

讲解Flutter 路由传递,这是一个大的概述图。


当 app 的页面变多的时候,就需要考虑页面传值的问题,在第一个页面如何把数据传递到 另外一个页面?最最基本的方法是在打开新页面,传递参数过去。但当 app 变得很大或者功能变多,你会发现传值是一件费劲的事情。例如前期设计的时候,只需要一个参数,但后面发现业务可能需要三个参数,如果再追加两个参数也不是不可以,就是不太优雅,而且可能要修改很多地方。


跳转到一个界面

先简单解释一下,下面会使用到, App 启动一个主界面,然后点击中间按钮,会打开第二个界面。点击第二个界面的右上角,会返回到之前的界面。具体代码如下:

import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';

class Test extends StatefulWidget {
  @override
  _TestState createState() => _TestState();
}

class _TestState extends State<Test> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('路由'),
      ),
      body: Center(
        child: FloatingActionButton(
          shape: BeveledRectangleBorder(),
          child: Text('按钮'),
          onPressed: () {
            //使用路由打开 第二个界面
            Navigator.push(
                context, MaterialPageRoute(builder: (context) => TwoPage()));
          },
        ),
      ),
    );
  }
}

class TwoPage extends StatefulWidget {
  @override
  _TwoPageState createState() => _TwoPageState();
}

class _TwoPageState extends State<TwoPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('第二页'),
      ),
      body: Column(
        children: <Widget>[
          SizedBox(height: 100),
          Text('传递过来的值:\n'),
          SizedBox(height: 100),
          Center(
            child: FloatingActionButton(
              shape: BeveledRectangleBorder(),
              child: Text('返回'),
              onPressed: () {
                // 返回到上一个界面
                Navigator.pop(context);
              },
            ),
          )
        ],
      ),
    );
  }
}


使用构造传参

使用构造参数把参数传递过去,在 TwoPage 中接受参数可直接用 widget.x , x 表示 _TwoPageState 传递过来的 widget 中包含值。

class _TestState extends State<Test> {
        ...
    onPressed: () {
        String name = "Wang";
        String age = "99";

        Navigator.push(context, MaterialPageRoute(builder: (context) => TwoPage(name, age)));
      },
    ...
}

class TwoPage extends StatefulWidget {
  String name;
  String age;

  TwoPage(this.name, this.age);
    ...
    Text('传递过来的值:\n ${widget.name}_${widget.age}'),
    ...
}

List(数组)传参

这里演示了 使用构造传递一个 List 类型的数, 使用 widget.data 的列表脚本获取数据。

class _TestState extends State<Test> {
        ...

        dynamic data = ['name1', 'age'];
    Navigator.push(context, MaterialPageRoute(builder: (context) => TwoPage(data)));

    ...
}

class TwoPage extends StatefulWidget {
    ...
    dynamic data;
    TwoPage(this.data);
    ...
}

class _TwoPageState extends State<TwoPage> {
    ...
    Text('传递过来的值:\n ${widget.data[0]}_${widget.data[1]}'),
    ...
}

Map 传参

这里演示了 使用构造传递一个 map 类型的数据。

class _TestState extends State<Test> {
        ...

        dynamic map = {
              'name': "Wang_Map",
              'age': "99",
            };
    Navigator.push(context, MaterialPageRoute(builder: (context) => TwoPage(map)));

    ...
}

class TwoPage extends StatefulWidget {
    ...
    dynamic map;
    TwoPage(this.map);
    ...
}

class _TwoPageState extends State<TwoPage> {
    ...
    Text('传递过来的值:\n ${widget.map["name"]}_${widget.map["age"]}'),
    ...
}


使用带名字的路由传参

很多时候我们项目比较大,为了统一管理,会使用带名字的路由概念,下面的路由字符串常量可以写成变量,这样后期不管怎么修改里面的值,依赖的地方都是不需要修改的。

传递一个参数

这里传递了一个 name 值,演示了一下 使用带名字的路由传递值。

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      initialRoute: "/",
      routes: {
        "/": (context) => OnePage(),
        "/TwoPage": (context) => TwoPage(),
      },
    );
  }
}


class OnePage extends StatefulWidget {
  @override
  _OnePageState createState() => _OnePageState();
}

class _OnePageState extends State<OnePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('路由页面'),
      ),
      body: Center(
        child: FloatingActionButton(
          shape: BeveledRectangleBorder(),
          child: Text('按钮'),
          onPressed: () {
            String name = "Wang";

            Navigator.pushNamed(context, '/TwoPage', arguments: name);

          },
        ),
      ),
    );
  }
}

class TwoPage extends StatefulWidget {

  @override
  _TwoPageState createState() => _TwoPageState();
}

class _TwoPageState extends State<TwoPage> {
  @override
  Widget build(BuildContext context) {
    dynamic name = ModalRoute.of(context).settings.arguments;

    return Scaffold(
      appBar: AppBar(
        title: Text('第二页'),
      ),
      body: Column(
        children: <Widget>[
          SizedBox(height: 100),
          Text('传递过来的值:\n $name'),
          SizedBox(height: 100),
          Center(
            child: FloatingActionButton(
              shape: BeveledRectangleBorder(),
              child: Text('返回'),
              onPressed: () {
                Navigator.pop(context);
              },
            ),
          )
        ],
      ),
    );
  }
}

传递 List(数组)

我们这里传递的是 List,可以根据角标进行获取对应值,前提是对值了解,一般这里会传递一个列表展示或者一个 List 包含多个不同的值,方便从上一次获取。

class _OnePageState extends State<OnePage> {
    ...
    onPressed: () {
        dynamic listData = ['name1', 'age'];
        Navigator.pushNamed(context, '/TwoPage', arguments: listData);
    }
    ...
}

class _TwoPageState extends State<TwoPage> {
  @override
  Widget build(BuildContext context) {
    dynamic listData = ModalRoute.of(context).settings.arguments;
    String name = listData[0];
    String age = listData[1];

        ...
        SizedBox(height: 100),
        Text('传递过来的值:\n $name _ $age'),
        SizedBox(height: 100),
        ...
  }
}

传递 Map

因为我们传递的是 map,所以在接收的时候需要做一次判断,用 is 判断,预防外界传入其他类型,造成我们程序红屏。这里可以从上一次获取多个不同的参数,使用不同名称获取,这里最好对接收到的值做判断,非空校验等。

class _OnePageState extends State<OnePage> {
    ...
    onPressed: () {
        dynamic listData = ['name1', 'age'];
        Navigator.pushNamed(context, '/TwoPage', arguments: listData);
    }
    ...
}

class _TwoPageState extends State<TwoPage> {
  @override
  Widget build(BuildContext context) {
    String name;
    String age;

    dynamic mapData = ModalRoute.of(context).settings.arguments;
    // 可以做一次校验数据安全,防止类型不匹配
    if (mapData is Map) {
      Map data = mapData;
      name = data['name'];
      age = data['age'];
    }

        ...
        SizedBox(height: 100),
        Text('传递过来的值:\n $name _ $age'),
        SizedBox(height: 100),
        ...
  }
}

普通路由带参

和带路由名字的方式基本一样,不过写的方式略有不同,需要把参数放入 settings 后面。

Navigator.of(context).push(new MaterialPageRoute(
  builder: (context) {
       return NewRouteWidget(); //写上要跳转到的页面
  },
   settings:
       RouteSettings(arguments: {'name': 'postbird'}), // 传参
   fullscreenDialog: true));

带参数从二级页面返回上一级

返回上一级:

Navigator.pop(context);

带参数返回上一级:

Navigator.pop(context, '返回的文本数据');

带类型的参数返回:

Navigator.pop<Map>(context, mapData);
Navigator.pop<List>(context, listData);
Navigator.pop<T>(context, data);

在上一级接受返回的值:

这里使用 then 接受,也可以使用 await, 只是这种方法更容易理解和接受,逻辑更强,代码简洁。

Navigator.pushNamed(context, '/TwoPage', arguments: mapData)
      .then((dynamic data) {
      print("返回的值是:$data");
});

原文:http://gdky005.com/2019/09/10/Flutter-如何在切换页面的时候,把参数传到下一个页面/

链接: http://www.fly63.com/article/detial/5246

实现一个前端路由,如何实现浏览器的前进与后退?

如果要你实现一个前端路由,应该如何实现浏览器的前进与后退 ?首先浏览器中主要有这几个限制,让前端不能随意的操作浏览器的浏览纪录:没有提供监听前进后退的事件。

Vue路由守卫之路由独享守卫

路由独立守卫,顾名思义就是这个路由自己的守卫任务,就如同咱们LOL,我们守卫的就是独立一条路,保证我们这条路不要被敌人攻克(当然我们也得打团配合)

Vue路由实现页面跳转的两种方式(router-link和JS)

Vue.js 路由可以通过不同的 URL 访问不同的内容,实现多视图的单页 Web 应用:通过 <router-link> 实现;<router-link> 组件用于设置一个导航链接,切换不同 HTML 内容

nginx 适配react-router browserRoute 路由问题

本文环境比较复杂,首先两层nginx转发,并且访问路径也不是根路径。加上对nginx一知半解,各路搜索一看,全程懵逼。最终没有一个能用的。最后还是靠同事帮助,文档大法结束加班。本文知识点:location优先级

使用 webpack 插件自动生成 vue 路由文件

一款自动生成 vue 路由文件的 webpack 插件 vue-route-webpack-plugin 在项目中试点成功了,现在在项目中已经不需要再维护路由配置文件了,由插件自动生成,节省了大家维护路由的时间。

理解Web路由

在Web开发过程中,经常会遇到『路由』的概念。那么,到底什么是路由?简单来说,路由就是URL到函数的映射。route就是一条路由,它将一个URL路径和一个函数进行映射

Flutter开发之导航与路由管理

所谓路由管理,就是管理页面之间如何跳转,也被称为导航管理。这和原生开发类似,无论是Android还是iOS,导航管理都是通过维护一个路由栈来实现的,路由入栈(push)操作对应打开一个新页面,路由出栈(pop)操作对应页面关闭操作

Vue 动态添加路由及生成菜单

写后台管理系统,估计有不少人遇过这样的需求:根据后台数据动态添加路由和菜单。为什么这么做呢?因为不同的用户有不同的权限,能访问的页面是不一样的。

从了解Hash和Html5 History 到简单实现路由

hash 属性是一个可读可写的字符串,该字符串是 URL 的锚部分(从 # 号开始的部分),在页面中的hash有多种功能意义:浏览器读取到hash之后自动滚动到该对应元素所在位置的可视区域内

vue-router之hash模式和history模式

hash模式即地址栏 URL 中的 # 符号(此 hash 不是密码学里的散列运算)。history模式利用了 HTML5 History Interface 中新增的 pushState() 和 replaceState() 方法。

fly63.com版权所有,内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权,请与小编联系!情况属实本人将予以删除!

广告赞助文章投稿关于web前端网站点搜索站长推荐网站地图站长QQ:522607023

小程序专栏: 土味情话心理测试脑筋急转弯幽默笑话段子句子语录成语大全