首页 > 解决方案 > 如何更新颤动警报框中的按钮文本

问题描述

我有一个颤振的警报框,提示用户输入姓名和日期。名称是一个简单的 TextField,通过单击按钮打开日期选择器来输入日期。最初,该按钮将当前日期作为文本。我希望在所选日期之前更新此日期,但无法实现。不过,当我返回文本输入时,它确实会更新。

谢谢你的帮助

我当前的代码如下所示。

Future<bool> getNameDate(BuildContext context)
  async
  {
    return showDialog<bool>(
      context: context,
      barrierDismissible: false,
      builder: (BuildContext context) {
        return AlertDialog(
          title: Text("Save Event"),
          content: new Column(
            children: <Widget>[
              new Expanded(
                child: new TextField(
                  autofocus: true,
                  decoration: new InputDecoration(
                      labelText: "Event Name"
                  ),
                  onChanged: (value) {
                    name = value;
                  },
                  onSubmitted: (value) {
                  },
                ),
              ),
              new Expanded(
                  child: new Row(
                    children: <Widget>[
                      new Text("Date of Event "),
                      new RaisedButton(
                          child: Text(DateFormat("dd/MM/yyyy").format(when)),
                          onPressed: () async {
                            DateTime picked = await showDatePicker(
                              context: context,
                              initialDate: when,
                              firstDate: DateTime(2015, 8),
                              lastDate: DateTime(2101),
                            );
                            setState(() {
                              when = picked ;
                            });
                          }),
                    ],
                  )
              )
            ],
          ),
          actions: <Widget>[
            new FlatButton(
                child: const Text('OK'),
                onPressed: () {
                  Navigator.of(context).pop(true);
                }),
            new FlatButton(
                child: const Text("CANCEL"),
                onPressed: () {
                  Navigator.of(context).pop(false);
                }),
          ],
        );
      },
    );
  }

对评论感到抱歉。如果能够以更好的方式回复答案,那就太好了。无论如何,我希望我可以创建一个更通用的“有状态对话框”所以我创建了这样的东西..

class StateDialog extends StatefulWidget
{
  final AlertDialog dialog;
  StateDialog({Key key, @required this.dialog}) : super (key: key);

  @override
  StateDialogState createState() => StateDialogState(dialog: dialog);

}

class StateDialogState extends State<StateDialog>
{
  final AlertDialog dialog;
  StateDialogState({@required this.dialog});
  @override
  Widget build(_) {
    return dialog;
  }
}

然后在我现有的功能中将其更改为..

    return showDialog<bool>(
      context: context,
      barrierDismissible: false,
      builder: (BuildContext context)
      {
        return StateDialog(dialog: AlertDialog(
          title: Text("Save Event"),
          content: new Column(
            children: <Widget>[
etc...

但这仍然不会更新日期按钮中的文本。我很乐意理解为什么。

标签: flutter

解决方案


那是因为该setState()方法实际上并没有更新alertDialog树上的小部件,而是更新了小部件。alertDialog没有自己的状态。您可以查看这篇文章,如果您想要这里的代码示例,您可以根据需要进行一些更改:

试试这个:我测试了它,在选择一个新日期后,按钮的文本会更新为您刚刚选择的正确日期!

import 'package:flutter/material.dart';
import 'package:intl/intl.dart';

void main() {
  runApp(new MaterialApp(
    home: new MyHomePage(),
  ));
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _selectedIndex = 0;

  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: AppBar(
        title: Text("StackoverFlow"),
      ),
      body: Container(),
      floatingActionButton: FloatingActionButton(
        onPressed: () async {
          await _dialogCall(context);
        },
      ),
    );
  }

  Future<void> _dialogCall(BuildContext context) {
    return showDialog(
        context: context,
        builder: (BuildContext context) {
          return MyDialog();
        });
  }
}

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

class _MyDialogState extends State<MyDialog> {
  String name = "";
  bool button = false;
  DateTime when = DateTime.now();

  @override
  Widget build(BuildContext context) {
    return AlertDialog(
      title: Text("Save Event"),
      content: new Column(
        children: <Widget>[
          new Expanded(
            child: new TextField(
              autofocus: true,
              decoration: new InputDecoration(labelText: "Event Name"),
              onChanged: (value) {
                name = value;
              },
              onSubmitted: (value) {},
            ),
          ),
          new Expanded(
              child: new Row(
            children: <Widget>[
              new Text("Date of Event "),
              new RaisedButton(
                  child: Text(DateFormat("dd/MM/yyyy").format(when)),
                  onPressed: () async {
                    DateTime picked = await showDatePicker(
                      context: context,
                      initialDate: when,
                      firstDate: DateTime(2015, 8),
                      lastDate: DateTime(2101),
                    );
                    setState(() {
                      when = picked;
                    });
                  }),
            ],
          ))
        ],
      ),
      actions: <Widget>[
        new FlatButton(
            child: const Text('OK'),
            onPressed: () {
              Navigator.of(context).pop(true);
            }),
        new FlatButton(
            child: const Text("CANCEL"),
            onPressed: () {
              Navigator.of(context).pop(false);
            }),
      ],
    );
  }

  Future<bool> getNameDate(BuildContext context) async {
    return showDialog<bool>(
      context: context,
      barrierDismissible: false,
      builder: (BuildContext context) {
        return AlertDialog(
          title: Text("Save Event"),
          content: new Column(
            children: <Widget>[
              new Expanded(
                child: new TextField(
                  autofocus: true,
                  decoration: new InputDecoration(labelText: "Event Name"),
                  onChanged: (value) {
                    name = value;
                  },
                  onSubmitted: (value) {},
                ),
              ),
              new Expanded(
                  child: new Row(
                children: <Widget>[
                  new Text("Date of Event "),
                  new RaisedButton(
                      child: Text(DateFormat("dd/MM/yyyy").format(when)),
                      onPressed: () async {
                        DateTime picked = await showDatePicker(
                          context: context,
                          initialDate: when,
                          firstDate: DateTime(2015, 8),
                          lastDate: DateTime(2101),
                        );
                        setState(() {
                          when = picked;
                        });
                      }),
                ],
              ))
            ],
          ),
          actions: <Widget>[
            new FlatButton(
                child: const Text('OK'),
                onPressed: () {
                  Navigator.of(context).pop(true);
                }),
            new FlatButton(
                child: const Text("CANCEL"),
                onPressed: () {
                  Navigator.of(context).pop(false);
                }),
          ],
        );
      },
    );
  }
}

推荐阅读