【问题标题】:Receive Response from pop navigator in Flutter在 Flutter 中接收来自 pop navigator 的响应
【发布时间】:2020-09-19 10:17:04
【问题描述】:

这是一个简单的代码示例,导航器推送一个名为的表单。并弹出答案。 我的目标是弹出一个对象,而不是字符串,但保持简单仍然行不通。

main.dart:

import 'package:flutter/material.dart';

import 'answer.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final appTitle = 'Form Validation Demo';

    return MaterialApp(
      title: appTitle,
      home: Scaffold(
        appBar: AppBar(
          title: Text(appTitle),
        ),
        body: ShowData(),
      ),
    );
  }
}

// Create a Form widget.
class MyCustomForm extends StatefulWidget {
  @override
  MyCustomFormState createState() {
    return MyCustomFormState();
  }
}

// Create a corresponding State class.
// This class holds data related to the form.
class MyCustomFormState extends State<MyCustomForm> {
  // Create a global key that uniquely identifies the Form widget
  // and allows validation of the form.
  //
  // Note: This is a GlobalKey<FormState>,
  // not a GlobalKey<MyCustomFormState>.
  final _formKey = GlobalKey<FormState>();
  final myController = TextEditingController();
  String stateData;
  @override
  void dispose() {
    // Clean up the controller when the widget is disposed.
    myController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    // Build a Form widget using the _formKey created above.
    return Scaffold(
      body: Form(
        key: _formKey,
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            TextFormField(
              controller: myController,
              validator: (value) {
                if (value.isEmpty) {
                  return 'Please enter some text';
                }
                return null;
              },
              onSaved: (value){
                stateData = value;
              },
            ),
            Padding(
              padding: const EdgeInsets.symmetric(vertical: 16.0),
              child: RaisedButton(
                onPressed: () {
                  // Validate returns true if the form is valid, or false
                  // otherwise.
                  if (_formKey.currentState.validate()) {
                    _formKey.currentState.save();
                    // If the form is valid, display a Snackbar.
                    Navigator.pop(context,stateData);
//                  Scaffold.of(context)
//                      .showSnackBar(SnackBar(content: Text(myController.text)));
//                    myController.text = 'look at me';
                  }
                },
                child: Text('Submit'),
              ),
            ),
          ],
        ),
      ),
    );
  }

}

answer.dart:

import 'package:flutter/material.dart';

import 'main.dart';

class ShowData extends StatefulWidget {

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

class _ShowDataState extends State<ShowData> {
  String data = 'start';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        floatingActionButton: FloatingActionButton(onPressed: (){
          String holder =  getFormData(context);
          setState(() {
            data = holder;
          });
        },
        elevation: 4,

        ),
        body:Text(data,style: TextStyle(fontSize: 80),));
  }

  String getFormData(BuildContext context) {
    final Future<String> answer =  Navigator.push(context,MaterialPageRoute(builder: (context)=>MyCustomForm()));
    answer.then((String value) {
        return value != null? value: 'empty';
      }
    );
  }
}

从表单返回时的错误信息是:

'package:flutter/src/widgets/text.dart': 断言失败: line ... pos... 'data!=null': 必须向 Text 提供非空字符串 小部件。

【问题讨论】:

    标签: flutter flutter-navigation flutter-form-builder


    【解决方案1】:

    添加await,接收Future的结果并返回值;

       Future<String> getFormData(BuildContext context) async {
        final result = await Navigator.push(
            context, MaterialPageRoute(builder: (context) => MyCustomForm()));
        return Future.value(result);
      }
    

    修改FloatingActionButton onPressed 代码以接收Future String

    onPressed: () async {
                final value = await getFormData(context);
                setState(() {
                  data = value;
                });
              },
    

    【讨论】:

      【解决方案2】:

      如果你想传递数据对象而不是字符串,这里有一段代码:

      main.dart:

      import 'package:flutter/material.dart';
      
      import 'answer.dart';
      
      void main() => runApp(MyApp());
      
      class MyApp extends StatelessWidget {
        @override
        Widget build(BuildContext context) {
          final appTitle = 'Form Validation Demo';
      
          return MaterialApp(
            title: appTitle,
            home: Scaffold(
              appBar: AppBar(
                title: Text(appTitle),
              ),
              body: ShowData(),
            ),
          );
        }
      }
      
      // Create a Form widget.
      class MyCustomForm extends StatefulWidget {
        @override
        MyCustomFormState createState() {
          return MyCustomFormState();
        }
      }
      
      // Create a corresponding State class.
      // This class holds data related to the form.
      class MyCustomFormState extends State<MyCustomForm> {
        // Create a global key that uniquely identifies the Form widget
        // and allows validation of the form.
        //
        // Note: This is a GlobalKey<FormState>,
        // not a GlobalKey<MyCustomFormState>.
        final _formKey = GlobalKey<FormState>();
        final myController = TextEditingController();
        Data stateData = Data();
        @override
        void dispose() {
          // Clean up the controller when the widget is disposed.
          myController.dispose();
          super.dispose();
        }
      
        @override
        Widget build(BuildContext context) {
          // Build a Form widget using the _formKey created above.
          return Scaffold(
            body: Form(
              key: _formKey,
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: <Widget>[
                  TextFormField(
                    controller: myController,
                    validator: (value) {
                      if (value.isEmpty) {
                        return 'Please enter some text';
                      }
                      return null;
                    },
                    onSaved: (value){
                      stateData.load = value;
                    },
                  ),
                  Padding(
                    padding: const EdgeInsets.symmetric(vertical: 16.0),
                    child: RaisedButton(
                      onPressed: () {
                        // Validate returns true if the form is valid, or false
                        // otherwise.
                        if (_formKey.currentState.validate()) {
                          _formKey.currentState.save();
                          // If the form is valid, display a Snackbar.
                          Navigator.pop(context,stateData);
      //                  Scaffold.of(context)
      //                      .showSnackBar(SnackBar(content: Text(myController.text)));
      //                    myController.text = 'look at me';
                        }
                      },
                      child: Text('Submit'),
                    ),
                  ),
                ],
              ),
            ),
          );
        }
      }
      
      class Data {
        String load;
      }
      

      answer.dart:

      import 'package:flutter/material.dart';
      
      import 'main.dart';
      
      class ShowData extends StatefulWidget {
      
        @override
        _ShowDataState createState() => _ShowDataState();
      }
      
      class _ShowDataState extends State<ShowData> {
        String data = 'start';
      
        @override
        Widget build(BuildContext context) {
          return Scaffold(
              floatingActionButton: FloatingActionButton(onPressed:   () async {
                final holder = await  getFormData(context);
                setState(() {
                  data = holder.load;
                });
              },
              elevation: 4,
      
              ),
              body:Text(data,style: TextStyle(fontSize: 80),));
        }
      
        Future<Data> getFormData(BuildContext context) async {
          final answer =  await Navigator.push(context,MaterialPageRoute(builder: (context)=>MyCustomForm()));
              return (Future.value(answer));
        }
      }
      

      【讨论】:

        猜你喜欢
        • 2018-09-17
        • 1970-01-01
        • 2021-08-22
        • 2020-05-13
        • 1970-01-01
        • 2022-12-18
        • 2013-05-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多