Flutter-DropdownButtonFormField值未更新

时间:2019-04-09 19:50:41

标签: dart flutter

在关闭并重新打开AlertDialog对话框之前,我的下拉菜单按钮的值不会更新。

我在班级顶部设置了变量

class _ItemListState extends State<ItemList> {
  int _ratingController;
...

}

在该类中,我有一个AlertDialog,可以打开一个表单,在这里,我具有DropdownButtonFormField


AlertDialog(
      content: Column(
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          TextField(
            controller: _eateryController,
            autofocus: true,
            decoration:
                InputDecoration(labelText: 'Eatery', hintText: 'eg Pizza Hut'),
          ),
          TextField(
            controller: _supplierController,
            decoration: InputDecoration(
                labelText: 'Supplier', hintText: 'eg Deliveroo'),
          ),
          TextField(
            controller: _descriptionController,
            decoration: InputDecoration(
                labelText: 'Description', hintText: 'eg cheese pizza'),
          ),
          DropdownButtonFormField<int>(
            value: _ratingController,
            items: [1, 2, 3, 4, 5]
                .map((label) => DropdownMenuItem(
                      child: Text(label.toString()),
                      value: label,
                    ))
                .toList(),
            hint: Text('Rating'),
            onChanged: (value) {
              setState(() {
                _ratingController = value;
              });
            },
          ),
        ],
      ),
      actions: <Widget>[
        FlatButton(
          onPressed: () {
            _handleSubmit(_eateryController.text, _supplierController.text,
                _descriptionController.text, _ratingController);
            Navigator.pop(context);
          },
          child: Text('Save'),
        ),
        FlatButton(
          onPressed: () => Navigator.pop(context),
          child: Text('Cancel'),
        )
      ],
    );

setState似乎没有动态更新字段值。关闭并重新打开AlertDialog后,更新后的值才会显示。

如何获取此即时更新?

谢谢

3 个答案:

答案 0 :(得分:2)

您可以在警报对话框中使用statefulBuilder。

return AlertDialog(
                                      title: new Text('Table'),
                                      content: StatefulBuilder(builder:
                                          (BuildContext context,
                                              StateSetter setState) {
                                        return Container(
                                          child: new SingleChildScrollView(
                                            scrollDirection: Axis.vertical,
                                            child: new Column(
                                              children: <Widget>[
                                                DropdownButtonFormField<String>(
                                                  value: dropdownValue,
                                                  style: TextStyle(
                                                      color: Colors.black87),
                                                  items: <String>[
                                                    'Lot 1',
                                                    'Lot 2',
                                                    'Lot 3',
                                                    'Lot 4',
                                                  ].map<
                                                          DropdownMenuItem<
                                                              String>>(
                                                      (String value) {
                                                    return DropdownMenuItem<
                                                        String>(
                                                      value: value,
                                                      child: Text(value),
                                                    );
                                                  }).toList(),
                                                  onChanged: (String newValue) {
                                                    setState(() {
                                                      dropdownValue = newValue;
                                                    });
                                                  },
                                                ),
```


答案 1 :(得分:1)

您似乎在错误的窗口小部件中呼叫setStateAlertDialog不属于ItemList的树,因为它位于另一个Route内。因此,在setState内部调用_ItemListState不会重建AlertDialog

请考虑将AlertDialog的内容提取到单独的StatefulWidget中并将int _ratingController置于其状态。

答案 2 :(得分:1)

您需要创建一个新的StatefulWidget类,该类应返回您的AlertDialog

class MyDialog extends StatefulWidget {
  @override
  _MyDialogState createState() => _MyDialogState();
}

class _MyDialogState extends State<MyDialog> {
  int _ratingController;

  @override
  Widget build(BuildContext context) {
    return AlertDialog(
      content: Column(
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          TextField(
            controller: _eateryController,
            autofocus: true,
            decoration:
            InputDecoration(labelText: 'Eatery', hintText: 'eg Pizza Hut'),
          ),
          TextField(
            controller: _supplierController,
            decoration: InputDecoration(
                labelText: 'Supplier', hintText: 'eg Deliveroo'),
          ),
          TextField(
            controller: _descriptionController,
            decoration: InputDecoration(
                labelText: 'Description', hintText: 'eg cheese pizza'),
          ),
          DropdownButtonFormField<int>(
            value: _ratingController,
            items: [1, 2, 3, 4, 5]
                .map((label) => DropdownMenuItem(
              child: Text(label.toString()),
              value: label,
            ))
                .toList(),
            hint: Text('Rating'),
            onChanged: (value) {
              setState(() {
                _ratingController = value;
              });
            },
          ),
        ],
      ),
      actions: <Widget>[
        FlatButton(
          onPressed: () {
            _handleSubmit(_eateryController.text, _supplierController.text,
                _descriptionController.text, _ratingController);
            Navigator.pop(context);
          },
          child: Text('Save'),
        ),
        FlatButton(
          onPressed: () => Navigator.pop(context),
          child: Text('Cancel'),
        )
      ],
    );
  }
}

像这样使用它

showDialog(
  context: context,
  builder: (context) {
    return MyDialog();
  },
);