Flutter NavigationDrawer Tutorial and Example

| Page Views: 500

Flutter Navigation Drawer Tutorial and Example.

This is a flutter navigation drawer tutorial with a full example. We start by discussing what navigation drawer is, when to use then look at a full example with fragments containing gridviews.

What is a Navigation Drawer?

A NavigationDrawer is a widget that allows us render navigation items in a sidebar with an optional user account profile. Navigation Drawer usually renders items in a ListView or ExpandableList. It usually has a header where we can display user account details like name, email, profile avatar et.

When a single navigation drawer item is clicked you navigate to a page or what we are calling fragments in this case.

When to use NavigationDrawer

Use navigation drawer when you have more items than can fit comfortably in a tabbar or bottomnavigation. Or if you find navigation drawer more intuitive to use of course.

Full Examples

1. Flutter Navigation Drawer - Fragments with GridViews

We will explore an example where we will render a navigation drawer with header containing user name, email as well as avatar. We will show a user image as avatar. We will also show a navigation drawer background image.

Then when the user clicks a single navigation drawer item we will open an associated fragment or page. That fragment will contain gridviews with some data.

We have three files:

  1. Fragments.dart - To define our Fragment classes. These are just stateless widgets.
  2. Home.dart - This is our home page. It's also where we define our navigation drawer.
  3. main.dart - The classic main file with our main method. Entry point to our application.
(a). Fragments.dart
import 'package:flutter/material.dart';

  //Let's create a reusable method that can render GridView as long as it passed a
  //a BuildContext as well as list of strings
  Widget createGridView(BuildContext context,List<String> cosmicBodies) {

    //I will shuffle my data
    cosmicBodies.shuffle();

   // Then build my GridView and return it
    return new GridView.builder(
      itemCount: cosmicBodies.length,
      gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
      itemBuilder: (BuildContext context, int index) {
        return new GestureDetector(
          child: new Card(
            elevation: 5.0,
            child: new Container(
              alignment: Alignment.centerLeft,
              margin: new EdgeInsets.only(top: 10.0, bottom: 10.0,left: 10.0),
              child: new Text(cosmicBodies[index]),
            ),
          ),
    );
    }
    );
  }
//Create Meteors Fragment. This will contains a gridview with our meteors
class Meteors extends StatelessWidget {
  @override
  Widget build(BuildContext context) {

    var meteors = ["Tunguska","Crab Pulsar","Geminga","Calvera","Vela X-1","Gaspra",
    "Psyche","Pallas","Ceres","Pioneer","Haumea","Makemake","Eris"];

    return createGridView(context, meteors);
  }
}

//Create Moons Fragment. This will contains a gridview with our moons
class Moons extends StatelessWidget {
  @override
  Widget build(BuildContext context) {

    var moons =  ["Phobos","Deimos","Moon","Triton","Proteus","Oberon","Umbriel","Ariel","Titan",
    "Rhea","Lapetus","Dione","Enceladus","Mimas","Ganymede","Callisto","IO","Europa"];

    return createGridView(context, moons);
  }
}

//Create Stars Fragment. This will contains a gridview with our stars
class Stars extends StatelessWidget {
  @override
  Widget build(BuildContext context) {

    var stars = ["UY Scuti","VY Cani Majoris","VV Cephei","KY Cygni","Aldebaran","Canopus",
    "Sirius","Vega","Alpha Pegasi","Bellatrix","Pollux","Betelgeuse","Naos","Arcturus","Polaris",
      "Rigel","Deneb","Wezen","Antares","Eya Caninae"];

    return createGridView(context, stars);
  }
}

//Create Galaxies Fragment. This will contains a gridview with our galaxies
class Galaxies extends StatelessWidget {
  @override
  Widget build(BuildContext context) {

    var galaxies = ["Messier 87","Andromeda","Sombrero","Whirlpool","Pinwheel","Milky Way",
    "Cartwheel", "Black Eye Galaxy","Star Bust","Centaurus","Triangulum","Sunflower",
    "Caldwell","Tadpole","Hoag's Object","Mallin 1","NGC 262","IC 1101"];

    return createGridView(context, galaxies);
  }
}
(b). Home.dart
import 'package:mr_nav_drawer/pages/Fragments.dart' as Fragments;
import 'package:flutter/material.dart';

//Let's define a DrawerItem data object
class DrawerItem {
  String title;
  IconData icon;
  DrawerItem(this.title, this.icon);
}
// Our Homepage
class HomePage extends StatefulWidget {
  //Let's define our drawer items, strings and images
  final drawerItems = [
    new DrawerItem("Meteors", Icons.strikethrough_s),
    new DrawerItem("Moons", Icons.place),
    new DrawerItem("Stars", Icons.stars),
    new DrawerItem("Galaxies", Icons.gavel)
  ];
  //Let's Create and Return state for this 'StatefulWidget'
  @override
  State<StatefulWidget> createState() {
    return new HomePageState();
  }
}
// Let's define state for our homepage. A state is just information for a widget.
class HomePageState extends State<HomePage> {
  int _selectedDrawerIndex = 0;

  //Let's use a switch statement to return the Fragment for a selected item
  _getDrawerFragment(int pos) {
    switch (pos) {
      case 0:
        return new Fragments.Meteors();
      case 1:
        return new Fragments.Moons();  
      case 2:
        return new Fragments.Stars();
      case 3:
        return new Fragments.Galaxies();

      default:
        return new Text("Error");
    }
  }
  //Let's update the selectedDrawerItemIndex the close the drawer
  _onSelectItem(int index) {
    setState(() => _selectedDrawerIndex = index);
    //we close the drawer
    Navigator.of(context).pop();
  }

  @override
  Widget build(BuildContext context) {
    List<Widget> drawerOptions = [];
    //Let's create drawer list items. Each will have an icon and text
    for (var i = 0; i < widget.drawerItems.length; i++) {
      var d = widget.drawerItems[i];
      drawerOptions.add(
        new ListTile(
          leading: new Icon(d.icon),
          title: new Text(d.title),
          selected: i == _selectedDrawerIndex,
          onTap: () => _onSelectItem(i),
        )
      );
    }
    //Let's scaffold our homepage
    return new Scaffold(
      appBar: new AppBar(
        // We will dynamically display title of selected page
        title: new Text(widget.drawerItems[_selectedDrawerIndex].title),
      ),
      // Let's register our Drawer to the Scaffold
      drawer: new Drawer(
        child: new Column(
          children: <Widget>[
            //Lets Create a material design drawer header with account name, email,avatar
            new UserAccountsDrawerHeader(
                accountName: new Text("Oclemy"),
                accountEmail: new Text("[email protected]"),
                currentAccountPicture: new CircleAvatar(backgroundImage:
                 new AssetImage("assets/profile.png"),),
            decoration: new BoxDecoration(
              image: new DecorationImage(
                image: new AssetImage("assets/bg.jpg"),
                fit: BoxFit.cover
              )
            ),
                ),
            new Column(children: drawerOptions)
          ],
        ),
      ),
      body: _getDrawerFragment(_selectedDrawerIndex),
    );
  }
}
(c). main.dart
import 'package:mr_nav_drawer/pages/Home.dart';
import 'package:flutter/material.dart';

//Lastly we come to our main app
class MyApp extends StatelessWidget {
  // This is the root of our application.
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Mr NavigationDrawer',
      theme: new ThemeData(
        primarySwatch: Colors.deepOrange,
      ),
      home: new HomePage(),
    );
  }
}

//Then we run our app
void main() => runApp(new MyApp());

Download the source code here.

How do You Feel after reading this?

According to scientists, we humans have 8 primary innate emotions: joy, acceptance, fear, surprise, sadness, disgust, anger, and anticipation. Feel free to tell us how you feel about this article using these emotes or via the comment section.

About Me.

After completing his Software Engineering bachelors program, Oclemy(Clement Ochieng) these days is a man of two lives. At day he works for a startup in Nairobi, Kenya. At night he works tirelessly on building ProgrammingWizards TV, a tv channel for student coders and this website to help share the source code. In between he practices Meditation and Self actualization to help him keep balance. He also likes going for long solo walks to connect more with nature.




Recommendations


What do You Think


Previous Post