dart - 在 Flutter 中的屏幕之间传递数据

在学习 Flutter 时,我开始学习导航。我想在屏幕之间传递数据,类似于 passing data between Activities in Android和 passing data between View Controllers in iOS .如何在 Flutter 中做到这一点?

相关问题:

  • The best way to passing data between widgets in Flutter
  • Flutter pass data between widgets?
  • Flutter/ How to pass and get data between Statefulwidget

最佳答案

这个答案将涵盖向前传递数据和向后传递数据。与 Android 事件和 iOS View Controller 不同,Flutter 中的不同屏幕只是小部件。在它们之间导航涉及创建称为路由的东西并使用 Navigator 将路由插入和弹出堆栈。

将数据转发到下一个屏幕

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

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

将数据传回前一屏幕

在传回数据时,您需要做以下事情:

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

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

    Navigator.pop(context, 'Hello');
    
  3. 然后在 FirstScreenawait 将完成,您可以使用结果。

    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);
  }
}

https://stackoverflow.com/questions/53861302/

相关文章:

dart - 错误 : Only static members can be accessed in

android - 如何将消息从 Flutter 传递到 Native?

dart - 在 Dart 中枚举或映射具有索引和值的列表

flutter - 如何更改 TextField 的高度和宽度?

flutter - 如何将大小设置为 CircularProgressIndicator?

flutter - Flutter 的 pubspec.yaml 中依赖版本号前的脱字符号 (^)

dart - 如何强制 Flutter 重建/重绘所有小部件?

flutter - 带 flutter 的最低安卓版本

listview - 在构建期间调用 setState() 或 markNeedsBuild

android - 让 Flutter 应用全屏显示