How to update the drawer content only

375

Drawer is a Stateless widget in itself

Placing your widget code in a function won't provide it a seperate state. It's essentially a part of the Main Widget, so the setState() calls are under Main Widget.

Make a seperate StatefulWidget (say MyStatefulDrawer), and place your Drawer Widget Code over there, with Drawer class as the root widget.

Now, use MyStatefulDrawer in your main widget as such:

@override
  Widget build(BuildContext context) {
    var key = GlobalKey<ScaffoldState>();
    return Scaffold(
      key: key,
      body: Text("Test Data"),
      bottomNavigationBar: NavBar(),
      drawer: MyStatefulDrawer(context),
    );
  }

Now that your drawer is Stateful, you can setState() within it and it'd be rebuilt with the updated value.

Share:
375
Robert Flesch
Author by

Robert Flesch

Updated on December 25, 2022

Comments

  • Robert Flesch
    Robert Flesch over 1 year

    We are using a Drawer to display the "settings" state. I would like the user to be able to change a setting and see the result reflected in the drawer.

    But when I call setState, it updates the parent window, not the Drawer state.

    I want the user to be able to change notification from 'none' to 'phone' and see the reflected in the drawer state. But instead it always shows original value.

      @override
      Widget build(BuildContext context) {
        var key = GlobalKey<ScaffoldState>();
        return Scaffold(
          key: key,
          body: Text("Test Data"),
          bottomNavigationBar: NavBar(),
          drawer: Drawer( child: components( context ) ),
        );
      }
    
    Widget components( context )
      {
        return ListView(
          children: <Widget>[
            ListTile( dense: true, leading: Icon(Icons.notifications), title: Text("Notifications"),
                trailing: DropdownButtonHideUnderline ( child: DropdownButton<String>(
                  value: Settings.notifications.toString().split('.')[1],
                  icon: Icon(Icons.expand_more),
                  onChanged: (String newValue) {
                    if ( 'none' == newValue )
                      Settings.notifications = Notifications.none;
                    else if ( 'email' == newValue )
                      Settings.notifications = Notifications.email;
                    else if ( 'phone' == newValue )
                      Settings.notifications = Notifications.phone;
                    else
                      Settings.notifications = Notifications.both;
                    setState(() {
                    });
                  },
                  items: <String>['none','email','phone','both']
                      .map<DropdownMenuItem<String>>((String value) {
                    return DropdownMenuItem<String>( value: value, child: Text(value), );
                  }).toList(),
                ) ),),
              ],
            );
        }
    

    enter image description here

    enter image description here

    • Jitesh Mohite
      Jitesh Mohite over 3 years
      So after selection you want to change the default text?
  • Robert Flesch
    Robert Flesch over 3 years
    That makes sense as to the stateful behavior. And when implemented it exhibits the desired behavior. However it no longer acts as a "drawer", that is covering only part of the screen and going away automagically. Do you know how to mimic that behavior?