Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter: setState on showDialog()

Tags:

flutter

dart

I need to update the value within the showDialog() [inside confirmBox()] function, when ' + ' or ' - ' is pressed; and render it onto the Container Widget. The setState() doesn't seem to work on that pop up Container. How do I go about doing this? (I'm a beginner)

int _n = 0; //counter variable 

void add() {
    setState(() {
      _n++; 
    });
  }

void minus() {
      setState(() {
        if (_n != 0) 
          _n--;
      });
    }

void confirmBox() {

    showDialog(
      context: context,
      builder: (BuildContext context){
        return Container(
          child: Scaffold(
            body: Column(
              children: <Widget>[
                Center(
                  child: Column(
                    children: <Widget>[
                      FloatingActionButton(
                        onPressed: add,
                        child: Icon(Icons.add, color: Colors.black,),
                        backgroundColor: Colors.white,),

                      Text("$_n", //_n value is not updating yet
                          style: TextStyle(fontSize: 60.0)),

                      FloatingActionButton(
                        onPressed: minus,
                        child: Icon(
                        const IconData(0xe15b, fontFamily: 'MaterialIcons'),
                          color: Colors.black),
                        backgroundColor: Colors.white,
                      ),
                    ],
                  ),
                ),
              ],
            ),
          ),
        );
      }
    );
  }


like image 606
nassqra Avatar asked Nov 21 '19 14:11

nassqra


3 Answers

EDIT: In this showDialog document, google say


EDIT2: This code will work

  int _n = 0; //counter variable

  void add(setState) {
    setState(() {
      _n++;
    });
  }

  void minus(setState) {
    setState(() {
      if (_n != 0) _n--;
    });
  }

  void confirmBox() {
    showDialog(
        context: context,
        builder: (BuildContext context) {
          return StatefulBuilder(builder: (context, StateSetter setState) {
            return Container(
              child: Scaffold(
                body: Column(
                  children: <Widget>[
                    Center(
                      child: Column(
                        children: <Widget>[
                          FloatingActionButton(
                            onPressed: () => add(setState),
                            child: Icon(
                              Icons.add,
                              color: Colors.black,
                            ),
                            backgroundColor: Colors.white,
                          ),
                          Text("$_n", //_n value is not updating yet
                              style: TextStyle(fontSize: 60.0)),
                          FloatingActionButton(
                            onPressed: () => minus(setState),
                            child: Icon(
                                const IconData(0xe15b,
                                    fontFamily: 'MaterialIcons'),
                                color: Colors.black),
                            backgroundColor: Colors.white,
                          ),
                        ],
                      ),
                    ),
                  ],
                ),
              ),
            );
          });
        });
  }

Use a StatefulBuilder or a custom StatefulWidget if the dialog needs to update dynamically.

Put this widget and other functions into new StatefulWidget

Container(
  child: Scaffold(
     body: Column(...

And call it inside builder of showDialog

like image 108
Ibrahim Karahan Avatar answered Oct 17 '22 13:10

Ibrahim Karahan


There can be two approaches,

Method 1

Just declare a StatefulBuilder or StatefulWidget inside your dialog.

Method 2

Declare a abstract class

abstract class AlertDialogCallback {
  void onPositive(Object object);
  void onNegative();
}

then implement this class to your widget like this,

class _ContactUsState extends State<ContactUs> implements AlertDialogCallback {
...
//open dialog and pass this to provide callback a context
 onPressed:(){CustomAlertDialog(this).openDialog();}

...
//
@override
  void onNegative() {
    Navigator.of(context).pop();
}

  @override
  void onPositive(Object object) {
// do your logic here
  }
}

Inside CustomAlertDialog get your mAlertDialogCallback and pass a object there

class CustomAlertDialog {
  AlertDialogCallback mAlertDialogCallback;

  CustomAlertDialog([this.mAlertDialogCallback]);

  openDialog() {
    // flutter defined function
    showDialog(
      builder: (BuildContext context) {
        // return object of type Dialog
        return AlertDialog(
          title: Text(title),
          content: Text(message),
          actions: <Widget>[
            // usually buttons at the bottom of the dialog
      FlatButton(
                    child: Text(
                      actionButtonText1.toString().toUpperCase(),
                    ),
                    onPressed: () {
                      Navigator.of(context).pop();
                      mAlertDialogCallback.onPositive(obj);
                    },
                  )
          ],
        );
      },
    );
  }
}
like image 6
Ravinder Kumar Avatar answered Oct 17 '22 13:10

Ravinder Kumar


Wrap all the content of the dialog inside of a StatefulBuilder: https://api.flutter.dev/flutter/widgets/StatefulBuilder-class.html

Example:

await showDialog<void>(
  context: context,
  builder: (BuildContext context) {
    int selectedRadio = 0;
    return AlertDialog(
      content: StatefulBuilder(
        builder: (BuildContext context, StateSetter setState) {
          return Column(
            mainAxisSize: MainAxisSize.min,
            children: List<Widget>.generate(4, (int index) {
              return Radio<int>(
                value: index,
                groupValue: selectedRadio,
                onChanged: (int value) {
                  setState(() => selectedRadio = value);
                },
              );
            }),
          );
        },
      ),
    );
  },
);
like image 6
Cristian Bregant Avatar answered Oct 17 '22 11:10

Cristian Bregant