Why StatefulWidget doesn't update when setState called?

Issue

I’m writing a program that uses floatingActionButton.
When OriginFloatingActionButton() called, showDialog() is called in the method.

Profile calls first.

@immutable
class Profile extends StatefulWidget {
  const Profile({Key? key}) : super(key: key);

  @override
  _Profile createState() => _Profile();
}

class _Profile extends State<Profile> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      floatingActionButton: OriginFloatingActionButton(),
      .......
    );
  }
}

Below code is showing floatingActionButton, and show dialog when it pushed.
In this dialog, when ElevatedButton pushed, add strings list element with setState.
However amount of element in ListView.builder isn’t updated.
When I close dialog and re-open it, it updated.
How can I update ListView.builder when push ElevatedButton.

class OriginFloatingActionButton extends StatefulWidget {
  const OriginFloatingActionButton({Key? key}) : super(key: key);

  @override
  _OriginFloatingActionButton createState() => _OriginFloatingActionButton();
}

class _OriginFloatingActionButton extends State<OriginFloatingActionButton> {
  List<String> strings = <String>[
    "abc"
  ];
  @override
  Widget build(BuildContext context) {
    return Container(
        margin: const EdgeInsets.only(bottom: 30.0, right: 30),
        width: 140,
        height: 55,
        child: SingleChildScrollView(
          child: FloatingActionButton.extended(
            label: const Text("Post"),
            icon: const Icon(Icons.add),
            backgroundColor: Colors.blue,
            foregroundColor: Colors.white,
            onPressed: () {
              showDialog(
                  context: context,
                  builder: (BuildContext context) {
                    return Dialog(
                        elevation: 16,
                        child: Container(
                          height: 700,
                          width: 500,
                          child: Center(
                            child: Column(
                              children: <Widget>[
                                Center(
                                  child: Row(
                                    mainAxisSize: MainAxisSize.min,
                                    children: [
                                      SizedBox(
                                          width: 300,
                                          child: Expanded(
                                              child: ListView.builder(
                                                  shrinkWrap: true,
                                                  itemCount:
                                                      strings.length,
                                                  itemBuilder:
                                                      (BuildContext context,
                                                          int index) {
                                                    return TextField(
                                                      decoration: InputDecoration(
                                                          label: Text(
                                                              "Artist Name " +
                                                                  index
                                                                      .toString()),
                                                          border:
                                                              const OutlineInputBorder()),
                                                    );
                                                  }))),
                                      const SizedBox(
                                        width: 5,
                                      ),
                                      ElevatedButton(
                                        child: const Icon(Icons.add),
                                        style: ElevatedButton.styleFrom(
                                            primary: Colors.white,
                                            onPrimary: Colors.black,
                                            shape: const CircleBorder(
                                                side: BorderSide(
                                                    color: Colors.black,
                                                    width: 1,
                                                    style: BorderStyle.solid))),
                                        onPressed: () {
                                          setState(() {
                                            if (mounted) {
                                              strings
                                                  .add("ABC");
                                            }
                                          });
                                        },
                                      ),
                               ........

Is this because that I call OriginFloatingActionButton() in floatingActionButton:?
So far no errors have occurred.
How can I update the ListView without refreshing the Dialog?

Solution

Use StatefulBuilder to use setState inside Dialog

showDialog(
  context: context,
  builder: (context) {
    return StatefulBuilder(
      builder: (context, setState) {
        return AlertDialog(
          title: Text("Title of Dialog"),
          content: Text(contentText),
          actions: <Widget>[
            TextButton(
              onPressed: () => Navigator.pop(context),
              child: Text("Cancel"),
            ),
            TextButton(
              onPressed: () {
                setState(() {
                  ///this will update 
                });
              },
              child: Text("Change"),
            ),
          ],
        );
      },
    );
  },
);

Answered By – Mofidul Islam

Answer Checked By – Terry (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *