【问题标题】:Returning data from a Stateful Widget in Flutter从 Flutter 中的 Stateful Widget 返回数据
【发布时间】:2019-07-08 16:51:10
【问题描述】:

我之前已经发布过我仍然面临的这个问题 也就是将数据从有状态小部件返回到无状态小部件

我使用的小部件是 DateTimePickerFormField 小部件,我在有状态小部件中将它用作子部件

所以我看过https://flutter.io/docs/cookbook/navigation/returning-data#complete-example

用于从小部件返回数据。但是,返回数据的小部件是无状态小部件......在我的情况下不是

所以代码如下

Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Add a Reminder'),

      ),
      body:
      new Container(
        padding: new EdgeInsets.all(20.0),
        child: new Form(
            child: new ListView(
              children: <Widget>[

            new TextFormField(
            keyboardType: TextInputType.text,
              // Use email input type for emails.
              decoration: new InputDecoration(
                hintText: 'Title of reminder',
              ),

            ),
            dateAndTimeWidget(context),
            RaisedButton(
            child: Text('Save'),
        onPressed: () {
          Navigator.pop(context);
        },
      )
      ],
    ),)
    ,
    )
    ,
    );

  }

那个小部件正在调用方法:dateAndTimeWidget,它应该返回 dateTime 有状态小部件并将输出的数据保存在一个变量中:

 dateAndTimeWidget(BuildContext context) async {
    final result = await Navigator.push(
      context,
      MaterialPageRoute(builder: (context)=> dateTime()),
    );

}

那么这是 dateTime Statful 小部件

class dateTime extends StatefulWidget{
    @override
  dateTimeState createState() => dateTimeState();

}
class dateTimeState extends State<dateTime>{

  static DateTime dateT;

  InputType inputType = InputType.both;

  final formats = {
    InputType.both: DateFormat("EEEE, MMMM d, yyyy 'at' h:mma"),
    InputType.date: DateFormat('yyyy-MM-dd'),
    InputType.time: DateFormat("HH:mm"),
  };

  Widget build(BuildContext context) => Container(
      child: DateTimePickerFormField(
        inputType: InputType.both,
        editable: true,
        format: formats[inputType],
        decoration: InputDecoration(
            labelText: 'Date/Time', hasFloatingPlaceholder: false),
        onChanged: (dt) {
          setState(() => dateT = dt);
          Navigator.of(context).pop(dateT);
        },

      )


  );


}

我还没有使用值结果 因为错误是我从来没有进入添加提醒页面,它说结果推送导航方法指向 null

【问题讨论】:

    标签: flutter widget


    【解决方案1】:

    在这种情况下,使用 Navigator 传递数据是不合适的。因为页面和您的dateTime Widget 之间没有页面转换。我建议您实现ValueChanged 回调以在同一屏幕的小部件之间传递数据。

    示例代码:

    这有点棘手。但是material.dart 的小部件经常使用这种技术。我希望这能帮到您!

    class MyHomePage extends StatefulWidget {
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      DateTime dateT;
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('Add a Reminder'),
          ),
          body: new Container(
            padding: new EdgeInsets.all(20.0),
            child: new Form(
              child: new ListView(
                children: <Widget>[
                  new TextFormField(
                    keyboardType: TextInputType.text,
                    // Use email input type for emails.
                    decoration: new InputDecoration(
                      hintText: 'Title of reminder',
                    ),
                  ),
                  dateTime(
                    onDateTimeChanged: (newDateTime) {
                      dateT = newDateTime;
                    },
                  ),
                  RaisedButton(
                    child: Text('Save'),
                    onPressed: () {
                      Navigator.pop(context);
                    },
                  )
                ],
              ),
            ),
          ),
        );
      }
    }
    
    class dateTime extends StatefulWidget {
      final ValueChanged<DateTime> onDateTimeChanged;
    
      dateTime({Key key, this.onDateTimeChanged}) : super(key: key);
    
      @override
      dateTimeState createState() => dateTimeState();
    }
    
    class dateTimeState extends State<dateTime> {
      DateTime dateT;
    
      InputType inputType = InputType.both;
    
      final formats = {
        InputType.both: DateFormat("EEEE, MMMM d, yyyy 'at' h:mma"),
        InputType.date: DateFormat('yyyy-MM-dd'),
        InputType.time: DateFormat("HH:mm"),
      };
    
      Widget build(BuildContext context) => Container(
            child: DateTimePickerFormField(
              inputType: InputType.both,
              editable: true,
              format: formats[inputType],
              decoration: InputDecoration(
                  labelText: 'Date/Time', hasFloatingPlaceholder: false),
              onChanged: (dt) {
                widget.onDateTimeChanged(dt);
              },
            ),
          );
    }
    

    (顺便说一句,你的dateAndTimeWidget 是一个方法,不是一个小部件。所以如果你将它分配给 Column 的子项(列表),Flutter 框架无法理解。)

    【讨论】:

      【解决方案2】:

      对于从另一个小部件返回值并使用它的更节省时间的解决方案,这是 Flutter Dropdown 的示例:

      import 'package:flutter/material.dart';
      import 'package:paxi_ride/constant.dart';
      
      class BuildDropdown extends StatefulWidget {
        final ValueChanged<String> onChanged;
        String defaultValue, selectedValue, dropdownHint;
        List<String> itemsList;
      
        BuildDropdown(
            {Key key,
            this.itemsList,
            this.defaultValue,
            this.dropdownHint,
            this.onChanged})
            : super(key: key);
      
        @override
        _BuildDropdownState createState() => _BuildDropdownState();
      }
      
      class _BuildDropdownState extends State<BuildDropdown> {
        String _value;
      
        @override
        Widget build(BuildContext context) {
          return Container(
            // height: 40,
            padding: EdgeInsets.symmetric(horizontal: 16, vertical: 0),
            margin: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
            color: Colors.white,
            child: DropdownButton<String>(
              items: widget.itemsList.map(
                (String value) {
                  return new DropdownMenuItem<String>(
                    value: value,
                    child: new Text(value),
                  );
                },
              ).toList(),
              value: _value == null ? widget.defaultValue : _value,
              isExpanded: true,
              onChanged: (String value) {
                setState(() {
                  _value = value;
                });
                widget.onChanged(value);
              },
              hint: Text(widget.dropdownHint),
              style: TextStyle(
                fontSize: 14,
                color: brownColorApp,
              ),
              iconEnabledColor: brownColorApp,
              iconSize: 14,
              underline: Container(),
            ),
          );
        }
      }
      

      从另一个小部件调用此小部件,您希望在其中获取选定值,如下所示:

      String selectedValue; //class field
      
      BuildDropdown(
                itemsList: ['Option 1','Option 2'],
                defaultValue: 'Option 1',
                dropdownHint: 'Select Required Option',
                onChanged: (value) {
                  selectedValue = value;
                },
              ),
      

      在需要的地方使用这个值,它会随着下拉选择的改变而改变。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-09-01
        • 1970-01-01
        • 2021-09-26
        • 2020-02-27
        • 1970-01-01
        • 2019-07-26
        • 2020-06-06
        • 2018-12-06
        相关资源
        最近更新 更多