How to refresh an AlertDialog in Flutter?

前端 未结 5 2306
萌比男神i
萌比男神i 2020-11-27 13:54

Currently, I have an AlertDialog with an IconButton. The user can click on the IconButton, I have two colors for each click. The problem is that I

相关标签:
5条回答
  • 2020-11-27 14:40

    Currently to retrieve the value of Dialog I use

    showDialog().then((val){
    setState (() {}); 
    print (val);
    });
    

    Example 1st screen

        onPressed: () { 
        showDialog(
           context: context,
           barrierDismissible: false,
           builder: (context) {
             return AddDespesa();
           }).then((val) {
             setState(() {});
             print(val);
            }
        );
       }
    

    2nd screen

    AlertDialog(
        title: Text("Sucesso!"),
        content: Text("Gasto resgristrado com sucesso"),
        actions: <Widget>[
        FlatButton(
          child: Text("OK"),
          onPressed: () {
             Navigator.pop(context, true);
          },
         ),
       ],
     );
    

    Will be printed true,

    0 讨论(0)
  • 2020-11-27 14:41

    First you need to use StatefulBuilder. Then i am setting _setState variable, which even could be used outside StatefulBuilder, to set new state.

    StateSetter _setState;
    String _demoText = "test";
    
    showDialog(
      context: context,
      builder: (BuildContext context) {
    
        return AlertDialog( 
          content: StatefulBuilder(  // You need this, notice the parameters below:
            builder: (BuildContext context, StateSetter setState) {
              _setState = setState;
              return Text(_demoText);
            },
          ),
        );
      },
    );
    

    _setState is used same way as setState method. For example like this:

    _setState(() {
        _demoText = "new test text";
    });
    
    0 讨论(0)
  • 2020-11-27 14:50

    Use StatefulBuilder to use setState inside Dialog and update Widgets only inside of it.

    showDialog(
      context: context,
      builder: (context) {
        String contentText = "Content of Dialog";
        return StatefulBuilder(
          builder: (context, setState) {
            return AlertDialog(
              title: Text("Title of Dialog"),
              content: Text(contentText),
              actions: <Widget>[
                FlatButton(
                  onPressed: () => Navigator.pop(context),
                  child: Text("Cancel"),
                ),
                FlatButton(
                  onPressed: () {
                    setState(() {
                      contentText = "Changed Content of Dialog";
                    });
                  },
                  child: Text("Change"),
                ),
              ],
            );
          },
        );
      },
    );
    
    0 讨论(0)
  • 2020-11-27 14:53

    The docs suggest that you use a StatefulBuilder in the content section of the AlertDialog. Even the StatefulBuilder docs actually have an example with a dialog.

    What it does is provide you with a new context and setState function to rebuild when needed.

    The sample code from the docs:

    showDialog(
      context: context,
      builder: (BuildContext context) {
    
        int selectedRadio = 0; // Declare your variable outside the builder
    
        return AlertDialog( 
          content: StatefulBuilder(  // You need this, notice the parameters below:
            builder: (BuildContext context, StateSetter setState) {
              return Column(  // Then, the content of your dialog.
                mainAxisSize: MainAxisSize.min,
                children: List<Widget>.generate(4, (int index) {
                  return Radio<int>(
                    value: index,
                    groupValue: selectedRadio,
                    onChanged: (int value) {
                      // Whenever you need, call setState on your variable
                      setState(() => selectedRadio = value);
                    },
                  );
                }),
              );
            },
          ),
        );
      },
    );
    

    And as I mentioned, this is what is said on the showDialog docs:

    [...] The widget returned by the builder does not share a context with the location that showDialog is originally called from. Use a StatefulBuilder or a custom StatefulWidget if the dialog needs to update dynamically.

    0 讨论(0)
  • 2020-11-27 15:01

    This is because you need to put your AlertDialog in its own StatefulWidget and move all state manipulation logic on the color there.

    Update:

    void main() => runApp(MaterialApp(home: Home()));
    
    class Home extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
            body: Center(
                child: RaisedButton(
          child: Text('Open Dialog'),
          onPressed: () {
            showDialog(
                context: context,
                builder: (_) {
                  return MyDialog();
                });
          },
        )));
      }
    }
    
    class MyDialog extends StatefulWidget {
      @override
      _MyDialogState createState() => new _MyDialogState();
    }
    
    class _MyDialogState extends State<MyDialog> {
      Color _c = Colors.redAccent;
      @override
      Widget build(BuildContext context) {
        return AlertDialog(
          content: Container(
            color: _c,
            height: 20.0,
            width: 20.0,
          ),
          actions: <Widget>[
            FlatButton(
                child: Text('Switch'),
                onPressed: () => setState(() {
                      _c == Colors.redAccent
                          ? _c = Colors.blueAccent
                          : _c = Colors.redAccent;
                    }))
          ],
        );
      }
    }
    
    0 讨论(0)
提交回复
热议问题