Search code examples
flutterstatepopupmenu

SetState() does not change my state in a PopupMenuButton


My screen bears a popup menu where the user can pass in expert mode by taping on a button (see the screen shot below).

enter image description here

But, though the setState() is being executed, the redraw always resets ìsExpertMode' to its default value (true).


class _SmartboxDashboard extends State<SmartboxDashboard>
    with
        Module<SmartboxDashboard>,
        SingleTickerProviderStateMixin, 
        AutomaticKeepAliveClientMixin<SmartboxDashboard> {

    /// Is expert mode?
    bool isExpertMode = true;

  
    return DefaultTabController(
      length: _tabSectionBodies.length,
      child: Scaffold(
        resizeToAvoidBottomInset: true,
        appBar: AppBar(
            bottom: TabBar(isScrollable: true, tabs: tabSectionTabs),
            title: Text(deviceDisplayName(widget.device.name)),
            actions: [
              PopupMenuButton(
                  icon: Icon(Icons.menu),
                  position: PopupMenuPosition.under,
                  itemBuilder: (context) {
                    return [
                      
                      PopupMenuItem<int>(
                          value: 2,
                          child: ListTile(
                              leading: ElevatedButton(
                                  child: Text(isExpertMode
                                      ? "Normal mode"
                                      : "Expert mode"),
                                  //value: isExpertMode,
                                  onPressed: () {
                                    setState(() {
                                      isExpertMode =
                                          appState.isExpertMode = !isExpertMode;
                                    });
                                  }),
                              title: Text(
                                  isExpertMode ? "Expert mode" : "Normal mode"),
                              subtitle: Text(isExpertMode
                                  ? "Turning to \"normal mode\" will streamline the information and you only see essentials informationabout your battery"
                                  : "Turning to \"expert mode\" will show more screens and deeper information about your batteries"),
                            )
                         ),
                      
                    ];
                  },
                  onSelected: (value) async {

                    switch (value) {
                      case 2:
                        //setState(() {
                        //  isExpertMode = appState.isExpertMode = !isExpertMode;
                        //  print("Expert mode turned to $isExpertMode");
                        });
                        break;
                    }
                    setState(() {
                      sharing = false;
                    });
                  }),
            ]),
        body: TabBarView(children: _tabSectionBodies),


Solution

  • you can use StatefulBuilder

    bool isSwitched = true;

     PopupMenuItem(child: StatefulBuilder(
                      builder: (BuildContext context,
                          void Function(void Function()) setState) {
                        return Switch(
                          value: isSwitched,
                          onChanged: (value) {
                            setState(() {
                              isSwitched = value;
                              print(isSwitched);
                            });
                          },
                          activeTrackColor: Colors.lightGreenAccent,
                          activeColor: Colors.green,
                        );
                      },
                    ))