11

When using the Flutter Scaffold.Drawer - is it possible to have the links in the Drawer change the content (Scaffold.body) on the page?

Similarly to having links in the navigation drawer change a Fragment in Android.

enter image description here

keikai
  • 14,085
  • 9
  • 49
  • 68
Martin
  • 227
  • 1
  • 4
  • 11

3 Answers3

26

You can simply change the state of the content of your interest by interacting with your Drawer items like this:

enter image description here

Here is the relevant code for this example:

class TestPage extends StatefulWidget {
  @override
  _TestPageState createState() => new _TestPageState();
}

class _TestPageState extends State<TestPage> {
  String text = "Initial Text";
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        drawer: new Drawer(
          child: new ListView(
            children: <Widget>[
              new Container(child: new DrawerHeader(child: new Container())),
              new Container (
                child: new Column(
                    children: <Widget>[
                      new ListTile(leading: new Icon(Icons.info),
                          onTap:(){
                              setState((){
                                text = "info pressed";
                              });
                          }
                      ),
                      new ListTile(leading: new Icon(Icons.save),
                          onTap:(){
                            setState((){
                              text = "save pressed";
                            });
                          }
                      ),
                      new ListTile(leading: new Icon(Icons.settings),
                          onTap:(){
                            setState((){
                              text = "settings pressed";
                            });
                          }
                      ),

                    ]
                ),
              )
            ],
          ),
        ),
        appBar: new AppBar(title: new Text("Test Page"),),
        body: new Center(child: new Text((text)),
        ));
  }
}
Shady Aziza
  • 50,824
  • 20
  • 115
  • 113
  • 1
    Just got started on flutter, exactly what I was looking for. All tutorials I found over the internet just create new widgets duplicating all the Scaffold that open-up as a new Activity. Thanks. – jasxir Aug 19 '18 at 09:07
  • 4
    You may want to enhance this by calling `Navigator.of(context).pop();` inside each on `onTap` property to close the drawer automatically instead of manually – Shady Aziza Aug 19 '18 at 09:48
  • Cool thanks. I was wondering if it's possible to achieve this using a navigator? – jasxir Aug 19 '18 at 09:54
  • Yes just use `Navigator.of(context).pop();` inside each `onTap` to close the drawer automatically. – Shady Aziza Aug 19 '18 at 09:56
  • That I understood, I mean the screen change, by adding a navigator as the `body`. – jasxir Aug 19 '18 at 09:58
  • I am not sure I understand the question – Shady Aziza Aug 19 '18 at 10:02
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/178292/discussion-between-jasxir-and-aziza). – jasxir Aug 19 '18 at 10:04
9

That's a very good solution from Aziza! Thank you. It works! I'd just want to add that it can also work for the whole body by replacing it with a widget state:

...
class _TestPageState extends State<TestPage> {
  String text = "Initial Text";
  Widget widgetForBody = SomeWidgetFromClass();
  ...
  ...
        children: <Widget>[
          new Container(child: new DrawerHeader(child: new Container())),
          new Container (
            child: new Column(
                children: <Widget>[
                  new ListTile(leading: new Icon(Icons.info),
                      onTap:(){
                          setState((){
                            widgetForBody = AnotherWidgetFromClass();
                          });
                      }
                  ),
                  new ListTile(leading: new Icon(Icons.save),
                      onTap:(){
                        setState((){
                          widgetForBody = YetAnotherWidgetFromClass();
                        });
                      }
                  ),
...
brightknight08
  • 546
  • 5
  • 14
4

You can use this for body of Scaffold:

        body: _getDrawerItemWidget(_selectedDrawerIndex));

and then in the main or state class do like so:

class HomePageState extends State<HomePage> {
  int _selectedDrawerIndex = 0;

  _getDrawerItemWidget(int pos) {
    switch (pos) {
      case 0:
        return new MainFragment();
      case 1:
          return new CardMgmt();
}
}
}

CardMgmt and other classes in switch case have their own build method that will return a Widget and it will be place in body of your scaffold. Also they can be in the same dart file or even another file.
But I have another problem:
What to do if instead of drawer items, we have a button in another class like CardMgmt and we want it to return a Widget and update page?

Mohsen Emami
  • 2,709
  • 3
  • 33
  • 40