TreeviewCopyright © aleen42 all right reserved, powered by aleen42

页面传值

在 Android 当中,我们通过 Intent 携带数据进行 Activity 之间的数据传递,在 Flutter 中,根据 Route 的构建方式的不同传值方式也分为两种。

使用构造方法

为目标 Route 创建一个带参的构造函数,跳转时,参数携带要传递的数据:

import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(
    title: 'Navigation Basics',
    routes: {
      "/": (BuildContext context) => HomeRoute(),
    },
  ));
}

class HomeRoute extends StatelessWidget {
  final userNameController = TextEditingController();
  final passwordController = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('First Route'),
      ),
      body: Center(
        child: Column(
          children: <Widget>[
            TextField(
              decoration: InputDecoration(
                hintText: "输入用户名",
              ),
              controller: userNameController,
            ),
            TextField(
              decoration: InputDecoration(
                hintText: "输入密碼",
              ),
              obscureText: true, //是否是密码
              controller: passwordController,
            ),
            MaterialButton(
              onPressed: () {
                //根据输入内容创建要传递的数据对象
                Person person =
                    Person(userNameController.text, passwordController.text);
                //跳转,并将 person 作为参数传入目标 Route
                Navigator.push(
                    context,
                    MaterialPageRoute(
                      builder: (BuildContext context) => SecondRoute(person),
                    ));
              },
              minWidth: double.infinity,
              child: Text("提交"),
              color: Colors.cyan,
            ),
          ],
        ),
      ),
    );
  }
}

class SecondRoute extends StatelessWidget {
  final Person person;

  SecondRoute(this.person);

  @override
  Widget build(BuildContext context) {
    String message;
    if (person.username == "tom" && person.password == "123") {
      message = "欢迎光临,tom";
    } else {
      message = "密码或用户名有错";
    }
    return Scaffold(
      appBar: AppBar(
        title: Text("Second Route"),
      ),
      body: Center(
        child: Text(message),
      ),
    );
  }
}

///数据对象
class Person {
  String username;
  String password;

  Person(this.username, this.password);
}

在上面的例子中,在转跳时,我们将需要传递的数据作为构造函数的参数传入,达到了传值的目的。

不使用构造方法

在上面的例子中,我们使用目标 Route 的带参构造函数来达成传值的目的,Flutter 其实还提供了更加“优雅”的传值方式,其实我也不觉得哪里优雅了,但好多文章说优雅,那就优雅吧。。。

那就是使用 RouteSettings 来进行值传递,对于构造 Route 来说,MaterialPageRoute 有一个 settings 参数,它是一个 RouteSettings 类型的对象,可以帮助我们在 Route 之间进行数值传递,使用方法如下:

Navigator.push(
    context,
    MaterialPageRoute(
        builder: (BuildContext context) => SecondRoute(),    //指定目标 Route
        settings: RouteSettings(    //通过 RouteSettings 传递数据
            arguments: person
        ),
    ));

对于目标 Route ,获取传递过来的值也非常简单,需要借助 ModalRoute.of() 方法可以帮助我们获取:

Person person = ModalRoute.of(context).settings.arguments;

对于命名 Route 的值传递,我们可以设置其 argument 参数进行值发送,然后通过上面的方法也一样可以获得上一个 Route 传递过来的值:

Navigator.pushNamed(context, "/SecondRoute", arguments: person);

回传数据

在 Android 中,我们使用 onActivityResult 来接收别的 Activity 回传过来的数据,在 Flutter 中,这一操作用到了异步,首先回传的页面同样是执行 pop 方法,只不过在参数中带上了需要回传的数据:

Navigator.pop(context, {"id": 11111, "name": "张三"});

在接收端需要用到异步来接受回传的数据。实际上,Navigator.push 方法的返回值就是一个 Future 对象,可以调用其 then 方法来获取传递过来的值:

            var future = Navigator.pushNamed(context, "Second",arguments: {"id": 123123, "name": "张三"});
            future.then((value) {
                //因为回传过来的数据会被当成是 Object 类型的,所以将其转换为 dynamic 类型的,方便获取数据。
              dynamic result = value;
              print("${result['id']}" + result['name']);
            });

也可以这样写:

onPressed: () {
    buttonClick(context);
},

buttonClick(BuildContext context) async  {
  dynamic value = await Navigator.pushNamed(context, "Second",arguments: {"id": 123123, "name": "张三"});
  print("${value['id']}" + value['name']);
}

有关 Futter 中的异步和 Future 的更多信息,请看这里 掘金 - 燃烧的鱼丸 - flutter实战5:异步async、await和Future的使用技巧

results matching ""

    No results matching ""