3

I'm creating a basic Material App and i have a drawer for navigation. With the simple way of pushing a route the whole widget is getting replaced and it's like opening a whole new page that includes a whole new drawer. My goal is to create the atmosphere of a page and a drawer, and when the user taps a drawer item the drawer will collapse and only the content of the page will be replaced.

I have found these two Questions/Answers:

  1. Replace initial Route in MaterialApp without animation?
  2. Flutter Drawer Widget - change Scaffold.body content

And my question is what is the best/correct way to achieve what i'm trying to do?

The 1st method is just creating the illusion by removing the push/pop animation, although it still actually behaves like the original method i described. The 2nd method actually replaces the content only, and the solution i thought of is instead of changing the text to create multiple Container widgets and changing between them.

Since i'm still new and learning flutter i would like to know what is the right practice to do so.

EDIT: I created this and it works pretty well. I still don't know about how effective/efficient it is but for now that's exactly what i wanted to achieve:

import 'package:flutter/material.dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(
        primarySwatch: Colors.blueGrey,
      ),
      home: new TestPage(),
    );
  }
}

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

class _TestPageState extends State<TestPage> {
  static final Container info = new Container(
    child: new Center(
        child: new Text('Info')
    ),
  );

  static final Container save = new Container(
    child: new Center(
        child: new Text('Save')
    ),
  );

  static final Container settings = new Container(
    child: new Center(
        child: new Text('Settings')
    ),
  );

  Container activeContainer = info;

  @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), title: new Text('Info'),
                          onTap:(){
                            setState((){
                              activeContainer = info;
                            });
                            Navigator.of(context).pop();
                          }
                      ),
                      new ListTile(leading: new Icon(Icons.save), title: new Text('Save'),
                          onTap:(){
                            setState((){
                              activeContainer = save;
                            });
                            Navigator.of(context).pop();
                          }
                      ),
                      new ListTile(leading: new Icon(Icons.settings), title: new Text('Settings'),
                          onTap:(){
                            setState((){
                              activeContainer = settings;
                            });
                            Navigator.of(context).pop();
                          }
                      ),

                    ]
                ),
              )
            ],
          ),
        ),
        appBar: new AppBar(title: new Text("Test Page"),),
        body: activeContainer,
        );
  }
}
argamanza
  • 1,122
  • 3
  • 14
  • 36

1 Answers1

2

Is not what you are trying to achieve is exactly what in the second answer, No ? :/

Here I am illustrating it by switching colors, but you can apply this to the content itself or basically any other widget.

enter image description here

class NavDrawer extends StatefulWidget {
  @override
  _NavDrawerState createState() => new _NavDrawerState();
}

class _NavDrawerState extends State<NavDrawer> {
  final GlobalKey<ScaffoldState> scaffoldKey = new GlobalKey<ScaffoldState>();
  Color contentColor = Colors.white;
  @override
  initState(){
    super.initState();
      }
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      key: scaffoldKey,
      appBar: new AppBar(),
      drawer: new Drawer(
        child: new ListView(
          children: <Widget>[
            new DrawerHeader(child: new Container()),
            new ListTile(title: new Text("Blue"),onTap: (){setState((){contentColor=Colors.blue;Navigator.pop(context);});},),
            new ListTile(title: new Text("Red"),onTap: (){setState((){contentColor=Colors.red;Navigator.pop(context);});},),
            new ListTile(title: new Text("Green"),onTap: (){setState((){contentColor=Colors.green;Navigator.pop(context);});},),
            new ListTile(title: new Text("Yellow"),onTap: (){setState((){contentColor=Colors.yellow;Navigator.pop(context);});},)

          ],
        ),
      ),
      body: new Container(
        color: contentColor,
      ),
    );
  }
}
Shady Aziza
  • 50,824
  • 20
  • 115
  • 113
  • Yep that's exactly what i'm trying to do, but my question is more about how effective and "correct" it is, and not how to do it since there are several workarounds. – argamanza Mar 10 '18 at 06:06
  • This is pretty normal in flutter, and it is really dependent on the type of data you are alternating on and your use cases. – Shady Aziza Mar 10 '18 at 06:08
  • Well since i'm pretty new to flutter i thought there might be a way to do it which is built-in and not such a "workaround", but if you say it's normal than it's great, thanks! – argamanza Mar 10 '18 at 06:30
  • This is not a workaround, however, it may be tedious if you have more complex view and did everything in one class, the state management is going to be painful, so make sure if what you are doing is rather complex to refactor each view into a separate class. – Shady Aziza Mar 10 '18 at 06:33