Nguyen Van Quang
Nguyen Van Quang

Reputation: 43

How to change navigation drawer hamburger menu icon to arrow icon when open/close drawer layout - Flutter?

When I created drawer layout following the Add a Drawer to a screen docs, it works OK. However, I have a problem, this is menu Icon.

In Android, I setup drawer layout with DrawerToggle and when I open drawer, menu icon is going to change to arrow icon and when I close drawer, arrow icon is going to change to menu icon.

In Flutter, it do not work as above.

If you understand my problem, please help me. I have search a lot, but not found solution. So I want to ask everyone. Thankyou so much.

enter image description here

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  final appTitle = 'Drawer Demo';

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: appTitle,
      home: MyHomePage(title: appTitle),
    );
  }
}

class MyHomePage extends StatelessWidget {
  final String title;

  MyHomePage({Key key, this.title}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text(title)),
      body: Center(child: Text('My Page!')),
      drawer: Drawer(
        // Add a ListView to the drawer. This ensures the user can scroll
        // through the options in the Drawer if there isn't enough vertical
        // space to fit everything.
        child: ListView(
          // Important: Remove any padding from the ListView.
          padding: EdgeInsets.zero,
          children: <Widget>[
            DrawerHeader(
              child: Text('Drawer Header'),
              decoration: BoxDecoration(
                color: Colors.blue,
              ),
            ),
            ListTile(
              title: Text('Item 1'),
              onTap: () {
                // Update the state of the app
                // ...
                // Then close the drawer
                Navigator.pop(context);
              },
            ),
            ListTile(
              title: Text('Item 2'),
              onTap: () {
                // Update the state of the app
                // ...
                // Then close the drawer
                Navigator.pop(context);
              },
            ),
          ],
        ),
      ),
    );
  }
}

Upvotes: 3

Views: 6765

Answers (3)

Gerald H
Gerald H

Reputation: 618

Below I attach a snippet of my code that I think is the easiest way to have a custom hamburger icon. The main part of the code is to use leading:!

return Scaffold(
    backgroundColor: Colors.white,
    appBar: AppBar(
      backgroundColor: Colors.transparent,
      elevation: 0.0,
      leading: Builder(
          builder: (context) => IconButton(
                icon: Icon(
                  Icons.sort,
                  color: Colors.black54,
                ),
                onPressed: () => Scaffold.of(context).openDrawer(),
                tooltip:
                    MaterialLocalizations.of(context).openAppDrawerTooltip,
              )),
    ),
    drawer: Drawer(
      child: ListView(
        padding: EdgeInsets.zero,
        children: <Widget>[
          DrawerHeader(
            decoration: BoxDecoration(
              color: Colors.blue,
            ),
            child: Text('App'),
          ),
          ListTile(
            title: Text('Item 1'),
            onTap: () {
              Navigator.pop(context);
            },
          ),
          ListTile(
            title: Text('Item 2'),
            onTap: () {
              Navigator.pop(context);
            },
          ),
        ],
      ),
    ),)

Upvotes: 0

Mangaldeep Pannu
Mangaldeep Pannu

Reputation: 3987

Use StateFulWidget so you can access setState method to change icon

In your state class

Define a Global Key

final GlobalKey<ScaffoldState> _key = GlobalKey();

Define a boolean to check whether Drawer is open.

bool _isDrawerOpen = false;

Add these to your state class

@override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Title'),
        leading: IconButton(
          icon: _isDrawerOpen ? Icon(Icons.menu) : Icon(Icons.arrow_back), 
          onPressed: onPressed,
        ),
      ),
      drawer: WillPopScope(child: Drawer(), onWillPop: onPop),
      body: //body
      key: this._key,
    );
  }

void onPressed() {
  if (!_isDrawerOpen) {
    this._key.currentState.openDrawer();
  } else {
    Navigator.pop(context);
  }
  setState(() {
    _isDrawerOpen = !_isDrawerOpen;
  });
}

void onPop() {
  if (_isDrawerOpen) {
    setState(() {
      _isDrawerOpen = false;
    });
  }
  Navigator.pop(context);
} 

Upvotes: 1

android
android

Reputation: 3090

To change hamburger icon while drawer open and also to display drawer below app bar:

I have declared "METHOD 1" and "METHOD 2" in my code which are in comments.

"METHOD 1" allows to open drawer and change icon with drawer controller callback.

"METHOD 2" allows to open drawer when we click hamburger icon The problem is if we used can't click on hamburger icon when use drawer controller.

import 'package:flutter/material.dart';

class MyNavDrawerController extends StatefulWidget {
  createState() {
    return StateKeeper();
  }
}

class StateKeeper extends State<MyNavDrawerController> {
  // Declare a new variable which will increment on FAB tap
  final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
  final appBarColor = const Color(0xFFd2527f);
  var myIcon = new Icon(Icons.list);

  DrawerCallback drawerCallback(bool status) {
    Fluttertoast.showToast(
        msg: "Drawer " + status.toString(),
        toastLength: Toast.LENGTH_SHORT,
        gravity: ToastGravity.CENTER,
        timeInSecForIos: 1,
        backgroundColor: appBarColor,
        textColor: Colors.white,
        fontSize: 14.0);
    setState(() {
      setMenuIcon(status);
    });
  }

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: _scaffoldKey,
      primary: true,
      appBar: AppBar(
        title: Text("Parent Scaffold"),
          leading: new IconButton(icon: myIcon,
              onPressed:(){
                _scaffoldKey.currentState.openDrawer();

              }
          )
      ),


      // METHOD 1
      /*body: DrawerController(
        child: Drawer(
          child: ListView(
            padding: EdgeInsets.zero,
            children: <Widget>[
              DrawerHeader(
                child: Text('Andy Rubin'),
                decoration: BoxDecoration(color: Colors.blue),
              ),
              ListTile(
                title: Text('Home'),
                onTap: () {
                  setState(() {
                    Navigator.pop(context);
                  });
                },
              ),
              ListTile(
                title: Text('About us'),
                onTap: () {
                  Navigator.pop(context);
                  Fluttertoast.showToast(
                      msg: "About us clicked! :)",
                      toastLength: Toast.LENGTH_SHORT,
                      gravity: ToastGravity.CENTER,
                      timeInSecForIos: 1,
                      backgroundColor: Colors.red,
                      textColor: Colors.white,
                      fontSize: 16.0);
                },
              ),
              ListTile(
                title: Text('Notifications'),
                onTap: () {
                  Navigator.pop(context);
                  Fluttertoast.showToast(
                      msg: "Notifications clicked! :)",
                      toastLength: Toast.LENGTH_SHORT,
                      gravity: ToastGravity.CENTER,
                      timeInSecForIos: 1,
                      backgroundColor: Colors.blue,
                      textColor: Colors.white,
                      fontSize: 18.0);
                },
              )
            ],
          ),
        ),
          alignment: DrawerAlignment.start, drawerCallback: drawerCallback
      ),*/


      // METHOD 2
      /*body: Scaffold(
        key: _scaffoldKey,
        drawer: Drawer(
          child: ListView(
            padding: EdgeInsets.zero,
            children: <Widget>[
              DrawerHeader(
                child: Text('Andy Rubin'),
                decoration: BoxDecoration(color: Colors.blue),
              ),
              ListTile(
                title: Text('Home'),
                onTap: () {
                  Fluttertoast.showToast(
                      msg: "Home clicked! :)",
                      toastLength: Toast.LENGTH_SHORT,
                      gravity: ToastGravity.CENTER,
                      timeInSecForIos: 1,
                      backgroundColor: appBarColor,
                      textColor: Colors.white,
                      fontSize: 14.0);
                  setState(() {
                    Navigator.pop(context);
                  });
                },
              ),
              ListTile(
                title: Text('About us'),
                onTap: () {
                  Navigator.pop(context);
                  Fluttertoast.showToast(
                      msg: "About us clicked! :)",
                      toastLength: Toast.LENGTH_SHORT,
                      gravity: ToastGravity.CENTER,
                      timeInSecForIos: 1,
                      backgroundColor: Colors.red,
                      textColor: Colors.white,
                      fontSize: 16.0);
                },
              ),
              ListTile(
                title: Text('Notifications'),
                onTap: () {
                  Navigator.pop(context);
                  Fluttertoast.showToast(
                      msg: "Notifications clicked! :)",
                      toastLength: Toast.LENGTH_SHORT,
                      gravity: ToastGravity.CENTER,
                      timeInSecForIos: 1,
                      backgroundColor: Colors.blue,
                      textColor: Colors.white,
                      fontSize: 18.0);
                },
              )
            ],
          ),
        ),
      )*/

    );
  }

  void setMenuIcon(bool isDrawerOpen){
    if(isDrawerOpen){
      myIcon = new Icon(Icons.list);
    }else{
      myIcon = new Icon(Icons.arrow_back);
    }
  }

}

Upvotes: 0

Related Questions