Alexandru Buruiana
Alexandru Buruiana

Reputation: 137

Flutter pop up dialog doesn't update on setState()

I have a problem with flutter, I created a pop up dialog when the user press a specific button, and he can check boxes inside it.

The problem is that the checkboxes aren't updated on setState(), just after I close the dialog pop up and open it again I can see that I check them.

It is not good that I have setState() inside a pop up dialog? I don't seem to see where it is the problem.

This is the code:

Edit: updated code:

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';

class AlwaysDisabledFocusNode extends FocusNode {
  @override
  bool get hasFocus => false;
}

class MultiLanguagePopupProduct extends StatefulWidget {
  @override
  _MultiLanguagePopupProductState createState() =>
      _MultiLanguagePopupProductState();
}

class _MultiLanguagePopupProductState extends State<MultiLanguagePopupProduct> {
  int selectedIndex = -1;

  String text = '';

  @override
  Widget build(BuildContext context) {
    return StatefulBuilder(
        builder: (context, setState) {
          return Container(
            child: TextField(
              focusNode: AlwaysDisabledFocusNode(),
              enableInteractiveSelection: false,
              decoration: InputDecoration(
                suffixIcon: IconButton(
                  icon: Icon(FontAwesomeIcons.boxOpen),
                ),
                labelText: 'Name and language: $text ',
                labelStyle:
                TextStyle(
                    fontWeight: FontWeight.bold, color: Colors.lightGreen),
              ),
              onTap: () =>
                  showDialog(
                    context: context,
                    builder: (context) {
                      return AlertDialog(
                        scrollable: true,
                        shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(10),
                        ),
                        title: Text('Multilanguage for product'),
                        content: Column(
                          children: <Widget>[
                            DataTable(
                              onSelectAll: (val) {
                                setState(() {
                                  selectedIndex = -1;
                                  text = '';
                                });
                              },
                              columns: [
                                DataColumn(label: Text('Language')),
                                DataColumn(label: Text('Translation')),
                              ],
                              rows: [
                                DataRow(
                                    selected: 0 == selectedIndex,
                                    onSelectChanged: (val) {
                                      setState(() {
                                        selectedIndex = 0;
                                        text = 'RO';
                                      }
                                      );
                                    },
                                    cells: [
                                      DataCell(
                                          Text(
                                            "RO",
                                            textAlign: TextAlign.left,
                                            style: TextStyle(
                                                fontWeight: FontWeight.bold),
                                          ), onTap: () {
                                        setState(() {
                                          selectedIndex = 0;
                                          text = 'RO';
                                          print('RO is clicked');
                                        });
                                      }),
                                      DataCell(
                                        TextField(
                                          decoration: InputDecoration(
                                              border: InputBorder.none,
                                              hintText: 'paine'),
                                        ),
                                      ),
                                    ]),
                                DataRow(
                                    selected: 1 == selectedIndex,
                                    onSelectChanged: (val) {
                                      setState(() {
                                        selectedIndex = 1;
                                        text = 'EN';
                                      });
                                    },
                                    cells: [
                                      DataCell(
                                          Text(
                                            "EN",
                                            textAlign: TextAlign.left,
                                            style: TextStyle(
                                                fontWeight: FontWeight.bold),
                                          ), onTap: () {
                                        setState(() {
                                          selectedIndex = 1;
                                          text = 'EN';
                                          print('EN is clicked');
                                        });
                                      }),
                                      DataCell(
                                        TextField(
                                          decoration: InputDecoration(
                                              border: InputBorder.none,
                                              hintText: 'bread'),
                                        ),
                                      ),
                                    ]),
                                DataRow(
                                    selected: 2 == selectedIndex,
                                    onSelectChanged: (val) {
                                      setState(() {
                                        selectedIndex = 2;
                                        text = 'FR';
                                      });
                                    },
                                    cells: [
                                      DataCell(
                                          Text(
                                            "FR",
                                            textAlign: TextAlign.left,
                                            style: TextStyle(
                                                fontWeight: FontWeight.bold),
                                          ), onTap: () {
                                        setState(() {
                                          selectedIndex = 2;
                                          text = 'FR';
                                          print('FR is clicked');
                                        });
                                      }),
                                      DataCell(
                                        TextField(
                                          decoration: InputDecoration(
                                              border: InputBorder.none,
                                              hintText: 'pain'),
                                        ),
                                      ),
                                    ]),
                              ],
                            ),
                          ],
                        ),
                        actions: <Widget>[
                          FlatButton(
                              onPressed: () => Navigator.of(context).pop(),
                              child: Text('OK')),
                          FlatButton(
                              onPressed: () => Navigator.of(context).pop(),
                              child: Text('CANCEL')),
                        ],
                      );
                    },
                  ),
            ),
          );
        },
    );
  }
}

Upvotes: 1

Views: 3314

Answers (2)

Dung Ngo
Dung Ngo

Reputation: 1452

StatefulBuilder is the correct answer. However, you are putting it in wrong place. You should put it inside showDialog(), not outside. I've implemented your code in codepen. Check it out.

showDialog(
  context: context,
  builder: (context) {
    return StatefulBuilder(
      builder: (context, setStateForDialog) {
        return AlertDialog();
      }
    );
  }
)

Upvotes: 2

Subaharan Vel
Subaharan Vel

Reputation: 261

To update Widgets only inside of it, Use StatefulBuilder to use setState inside Dialog

 showDialog(
  context: context,
   builder: (context) {
   String contentText = "Content of Dialog";
    return StatefulBuilder(
     builder: (context, setState) {
      return AlertDialog(
      title: Text("Title Text"),
      content: Text(contentText),
      actions: <Widget>[
        FlatButton(
          onPressed: () => Navigator.pop(context),
          child: Text("Cancel"),
        ),
        FlatButton(
          onPressed: () {
            setState(() {
              contentText = "Changed Content of your Dialog";
            });
          },
          child: Text("Change Text"),
         ),
        ],
      );
    },
   );
  },
);

Upvotes: 5

Related Questions