推荐答案

这个答案将包括向前传递数据和向后传递数据.与Android Activities和iOS ViewController不同,Flatter中的不同屏幕只是小部件.在它们之间导航需要创建一个称为路由的东西,并使用Navigator在堆栈上推送和弹出路由.

Passing data forward to the next screen

enter image description here

要将数据发送到下一个屏幕,请执行以下操作:

  1. 使SecondScreen构造函数接受要发送给它的数据类型的参数.在该特定示例中,数据被定义为String值,并且在这里设置为this.text.

    class SecondScreen extends StatelessWidget {
      final String text;
      SecondScreen({Key key, @required this.text}) : super(key: key);
    
      ...
    
  2. 然后使用FirstScreen小部件中的Navigator将路由推送到SecondScreen小部件.您将想要作为参数发送的数据放入其构造函数中.

    Navigator.push(
        context,
        MaterialPageRoute(
          builder: (context) => SecondScreen(text: 'Hello',),
        ));
    

main.dart的完整代码如下:

import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(
    title: 'Flutter',
    home: FirstScreen(),
  ));
}

class FirstScreen extends StatefulWidget {
  @override
  _FirstScreenState createState() {
    return _FirstScreenState();
  }
}

class _FirstScreenState extends State<FirstScreen> {

  // this allows us to access the TextField text
  TextEditingController textFieldController = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('First screen')),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [

          Padding(
            padding: const EdgeInsets.all(32.0),
            child: TextField(
              controller: textFieldController,
              style: TextStyle(
                fontSize: 24,
                color: Colors.black,
              ),
            ),
          ),

          RaisedButton(
            child: Text(
              'Go to second screen',
              style: TextStyle(fontSize: 24),
            ),
            onPressed: () {
              _sendDataToSecondScreen(context);
            },
          )

        ],
      ),
    );
  }

  // get the text in the TextField and start the Second Screen
  void _sendDataToSecondScreen(BuildContext context) {
    String textToSend = textFieldController.text;
    Navigator.push(
        context,
        MaterialPageRoute(
          builder: (context) => SecondScreen(text: textToSend,),
        ));
  }
}

class SecondScreen extends StatelessWidget {
  final String text;

  // receive data from the FirstScreen as a parameter
  SecondScreen({Key key, @required this.text}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Second screen')),
      body: Center(
        child: Text(
          text,
          style: TextStyle(fontSize: 24),
        ),
      ),
    );
  }
}

Passing data back to the previous screen

enter image description here

在传回数据时,您需要执行以下操作:

  1. FirstScreen中,使用Navigatorasync方法中推送(启动)SecondScreen,并等待它完成时返回的结果.

    final result = await Navigator.push(
        context,
        MaterialPageRoute(
          builder: (context) => SecondScreen(),
        ));
    
  2. SecondScreen中,包括弹出Navigator时要作为参数传回的数据.

    Navigator.pop(context, 'Hello');
    
  3. 然后,在FirstScreen米中,await将结束,您可以使用结果.

    setState(() {
      text = result;
    });
    

下面是main.dart的完整代码,供您参考.

import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(
    title: 'Flutter',
    home: FirstScreen(),
  ));
}

class FirstScreen extends StatefulWidget {
  @override
  _FirstScreenState createState() {
    return _FirstScreenState();
  }
}

class _FirstScreenState extends State<FirstScreen> {

  String text = 'Text';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('First screen')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [

            Padding(
              padding: const EdgeInsets.all(32.0),
              child: Text(
                text,
                style: TextStyle(fontSize: 24),
              ),
            ),

            RaisedButton(
              child: Text(
                'Go to second screen',
                style: TextStyle(fontSize: 24),
              ),
              onPressed: () {
                _awaitReturnValueFromSecondScreen(context);
              },
            )

          ],
        ),
      ),
    );
  }

  void _awaitReturnValueFromSecondScreen(BuildContext context) async {

    // start the SecondScreen and wait for it to finish with a result
    final result = await Navigator.push(
        context,
        MaterialPageRoute(
          builder: (context) => SecondScreen(),
        ));

    // after the SecondScreen result comes back update the Text widget with it
    setState(() {
      text = result;
    });
  }
}

class SecondScreen extends StatefulWidget {
  @override
  _SecondScreenState createState() {
    return _SecondScreenState();
  }
}

class _SecondScreenState extends State<SecondScreen> {
  // this allows us to access the TextField text
  TextEditingController textFieldController = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Second screen')),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [

          Padding(
            padding: const EdgeInsets.all(32.0),
            child: TextField(
              controller: textFieldController,
              style: TextStyle(
                fontSize: 24,
                color: Colors.black,
              ),
            ),
          ),

          RaisedButton(
            child: Text(
              'Send text back',
              style: TextStyle(fontSize: 24),
            ),
            onPressed: () {
              _sendDataBack(context);
            },
          )

        ],
      ),
    );
  }

  // get the text in the TextField and send it back to the FirstScreen
  void _sendDataBack(BuildContext context) {
    String textToSendBack = textFieldController.text;
    Navigator.pop(context, textToSendBack);
  }
}

Flutter相关问答推荐

为什么他们实例化类,然后丢弃该实例?

轻松本地化包翻译在底部导航栏项目标签Flutter 翼dart 中不起作用

如何使DropDownMenu宽度等于TextFormfield?

导航回上一页会将我带回Ffltter应用程序中的登录页面

当我转到其他屏幕并按下后退按钮时,屏幕将不会刷新

我如何在Android 13中通过Flutter应用程序打开文件(不是图像、视频或音频)?

Flutter Riverpod 对提供者状态的变化做出react

如何在Flutter中的textField中在可编辑文本和前缀图标之间添加空格?

为什么我们需要使用ChangeNotifierProvider而不是仅仅使用ChangeNotifier?

获取通过列表呈现的相同 TextEditingController 的值

升级到 Flutter 3.10 后,Flutter 键盘填充不起作用. Flutter 3.10 如何防止 BottomSheet 被键盘覆盖?

Freezed+BLoc 如何从 BLoc Listener 查看当前状态和特定状态的变量

减少 Flutter 中 API 的连接等待时间

如何使用 Rrect 或类似工具在 flutter 中绘制梯形线?

在 CircleAvatar 中放置芯片

Future.wait() 中的 futures 可以顺序调用吗?

避免长单词中断

使用 Chaquopy 插件后 Gradle Sync 无法正常工作

根据索引/变量更改小部件的 colored颜色

检索 api 的值时,我得到_TypeError(类型'Null'不是'String'类型的子类型)