Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the right way to navigate using a drawer and change only the content of the body?

Tags:

flutter

dart

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,
        );
  }
}
like image 964
argamanza Avatar asked Dec 17 '25 18:12

argamanza


1 Answers

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,
      ),
    );
  }
}
like image 60
Shady Aziza Avatar answered Dec 21 '25 00:12

Shady Aziza



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!