代码之家  ›  专栏  ›  技术社区  ›  Suragch Shmidt

在颤振中在屏幕之间传递数据

  •  0
  • Suragch Shmidt  · 技术社区  · 7 年前
    1 回复  |  直到 7 年前
        1
  •  185
  •   Suragch Shmidt    7 年前

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

    将数据转发到下一屏幕

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

    将数据传回上一屏幕

    enter image description here

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

    1. 第一屏 ,使用 领航员 在一个 async 方法并等待完成时返回的结果。

      final result = await Navigator.push(
          context,
          MaterialPageRoute(
            builder: (context) => SecondScreen(),
          ));
      
    2. 第二屏 ,包括在弹出 .

      Navigator.pop(context, 'Hello');
      
    3. 然后在 第一屏 这个 await 将完成,您可以使用结果。

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

    下面是完整的代码 主飞镖 供你参考。

    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);
      }
    }
    
        2
  •  34
  •   Suragch Shmidt    6 年前

    获得完美的解决方案:

    1. 从第一个屏幕导航到其他屏幕,如下所示:

      Navigator.pushNamed(context, "second",arguments: {"name" : 
        "Bijendra", "rollNo": 65210});
      },
      
    2. 在构建方法的第二个屏幕上,获取为:

      @override
      Widget build(BuildContext context) {
          final  Map<String, Object>rcvdData = ModalRoute.of(context).settings.arguments;
          print("rcvd fdata ${rcvdData['name']}");
          print("rcvd fdata ${rcvdData}");
      
          return Scaffold(appBar: AppBar(title: Text("Second")),
            body: Container(child: Column(children: <Widget>[
            Text("Second"),
          ],),),);
      
      }
      
        3
  •  30
  •   CopsOnRoad    5 年前

    通过在构造函数中传递变量,此解决方案非常简单:

    第一页:

    Navigator.of(context).push(MaterialPageRoute(builder:(context)=>SecondPage('something')));
    

    第二页:

    class SecondPage extends StatefulWidget {
      String something;
      SecondPage(this.something);
      @override
      State<StatefulWidget> createState() {
        return SecondPageState(this.something);
      }
    }
    class SecondPageState extends State<SecondPage> {
      String something;
      SecondPageState(this.something);
      @override
      Widget build(BuildContext context) {
       return Scaffold(
        appBar: AppBar(
        //now you have passing variable
        title: Text(something),
       ),
       ...
      }
    
        4
  •  27
  •   user11065582 user11065582    7 年前

    第一页,省道

     Navigator.push(
              context,
              MaterialPageRoute(
                  builder: (context) => PasswordRoute(usernameController)));
    

    //usernameController是字符串值,如果要传递多个值,请全部添加

    第二页,省道

    class PasswordRoute extends StatefulWidget {
      final String usernameController;//if you have multiple values add here
    PasswordRoute(this.usernameController, {Key key}): super(key: key);//add also..example this.abc,this...
    
      @override
      State<StatefulWidget> createState() => _PasswordPageState();
    }
    
    class _PasswordPageState extends State<PasswordRoute> {
     @override
      Widget build(BuildContext context) {
    ...child: Text(widget.usernameController);
    }
    }
    
        5
  •  9
  •   serg    6 年前

    https://pub.dev/packages/provider

    看看这部电影,或者观看Andrea Bizzotto的以下视频: https://www.youtube.com/watch?v=MkFjtCov62g //提供者:基本指南 https://www.youtube.com/watch?v=O71rYKcxUgA&t=258s

    了解如何使用提供商软件包,您将终身受益:)

        6
  •  3
  •   Varsha    6 年前

     Navigator.push(context, MaterialPageRoute(builder: (context) {
                              return WelcomeUser(usernameController.text);
    
                              }));
    

    第二屏: //从第一个屏幕获取数据

     final String username;
      WelcomeUser(this.username);
    

    //使用数据显示

    body: Container(
        child: Center(
          child: Text("Welcome "+widget.username,
          textAlign: TextAlign.center,
          ),
        ),
      ),
    
        7
  •  3
  •   Hasan A Yousef Michael Benjamin    5 年前

    Flitter中的导航器与Android中的意图类似。

    要在第一个屏幕和第二个屏幕之间传递数据,请执行以下操作: 首先,在SecondScreen类构造函数中添加参数

    现在在FirstScreen类中提供参数

    Navigator.push(context, MaterialPageRoute(builder: (context)=>SecondScreen(key_name:"Desired Data"));
    

    因此,在上面的一行中,“key_name”是SecondScreen类中给定的参数的名称。 “所需数据”是指数据应通过键传递到SecondScreen类。

    就这样,你完了!!!

        8
  •  0
  •   Anil Kumar    6 年前

    1) 从要推送的位置:

    onPressed: () async {
                            await Navigator.pushNamed(context, '/edit',
                                arguments: userData);
                            setState(() {
                              userData = userData;
                            });}
    

        void updateData() async{
        WorldTime instance = locations;
        await instance.getData();
        Navigator.pop(context, userData);
      }
    
        9
  •  0
  •   Jewel Rana    5 年前

    如果您使用get软件包,请尝试此方法。 passing data with get package

    查收包裹 package link

        10
  •  0
  •   Tommie C.    5 年前

    其他答案没有错。我已经尝试过使用全球范围的小部件(如提供者、第三方解决方案、导航器参数等)所提到的所有方法。这种方法的不同之处在于允许一个人链接调用,并向使用它的小部件传递所需的任何类型的精确数据。我们还可以获得对完成处理程序事件的访问权,并且可以在不受导航器对象约束的情况下使用此技术。

    以下是tldr:

    太长,读不下去了我们必须稍微改变一下我们的想法。数据可以是 目标小部件中具有默认值的参数。使用 小装置。

    完整的解释可以使用此 SO answer. , (Gist)