40

The drawer has this default three horizontal bars as default icon but I want to change it to something else.
I have checked the possible options under the Drawer(), but no property seems to be attached to that.

Nimantha
  • 6,405
  • 6
  • 28
  • 69
lordvidex
  • 3,581
  • 3
  • 17
  • 25

10 Answers10

91

This should work.

Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title:Text('hi'),
        leading: IconButton(
          icon: Icon(Icons.accessible),
          onPressed: () => Scaffold.of(context).openDrawer(),
        ),
      ),
);

From the docs ->

{Widget leading} Type: Widget
A widget to display before the [title]. If this is null and [automaticallyImplyLeading] is set to true, the [AppBar] will imply an appropriate widget. For example, if the [AppBar] is in a [Scaffold] that also has a [Drawer], the [Scaffold] will fill this widget with an [IconButton] that opens the drawer (using [Icons.menu]). If there's no [Drawer] and the parent [Navigator] can go back, the [AppBar] will use a [BackButton] that calls [Navigator.maybePop]. The following code shows how the drawer button could be manually specified instead of relying on [automaticallyImplyLeading]:

import 'package:flutter/material.dart';
Widget build(context) {
  return AppBar(
    leading: Builder(
      builder: (BuildContext context) {
        return IconButton(
          icon: const Icon(Icons.menu),
          onPressed: () {
            Scaffold.of(context).openDrawer();
          },
          tooltip: MaterialLocalizations.of(context).openAppDrawerTooltip,
        );
      },
    ),
  );
}

The [Builder] is used in this example to ensure that the context refers to that part of the subtree. That way this code snippet can be used even inside the very code that is creating the [Scaffold] (in which case, without the [Builder], the context wouldn't be able to see the [Scaffold], since it would refer to an ancestor of that widget).

cmd_prompter
  • 1,566
  • 10
  • 16
  • 4
    In my case I'm getting "The following assertion was thrown while handling a gesture: Scaffold.of() called with a context that does not contain a Scaffold. No Scaffold ancestor could be found starting from the context that was passed to Scaffold.of(). This usually happens when the context provided is from the same StatefulWidget as that whose build function actually creates the Scaffold widget being sought." – vinod yadav Feb 22 '20 at 17:02
  • 2
    Refer to the second part of the answer @vinodyadav – cmd_prompter Dec 09 '20 at 14:35
  • do not forget to add : 'drawer: NavigationDrawer()' – Vipin Krishna Apr 04 '22 at 17:12
  • @cmd_prompter why first code is not working??, it looks more easy.. – Vivek Thummar Jun 02 '22 at 12:32
28
appBar: AppBar(
        leading: Builder(
          builder: (context) => IconButton(
            icon: Icon(Icons.menu_rounded),
            onPressed: () => Scaffold.of(context).openDrawer(),
          ),
        ),
        title: Text(
          "Track your Shipment",
        ),
      ),
Charles Vinoth
  • 281
  • 3
  • 2
14

You can open a drawer with a custom button like this too. create this scaffold key.

var scaffoldKey = GlobalKey<ScaffoldState>();

now added a scaffolled in your state class like this

      @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: scaffoldKey,
      drawer: Drawer(
        child: Text('create drawer widget tree here'),
      ),
      appBar: AppBar(
        backgroundColor: Colors.white,
        title: Text(
          'appName',
          style: Theme.of(context).textTheme.headline2,
        ),
        leading: IconButton(
          onPressed: () {
            scaffoldKey.currentState?.openDrawer();
          },
          icon: Image.asset(
            'assets/images/menu.png',
            fit: BoxFit.cover,
          ),
        ),
      ),
      body: Container(),
    );
  }

enter image description here

Nimantha
  • 6,405
  • 6
  • 28
  • 69
Himani Sharma
  • 1,550
  • 2
  • 10
  • 12
2

Lets say you have: index.dart (where you want to use the appbar), drawer.dart (your drawer or navigation menu) and appbar.dart (your appbar)

you can do this in drawer:

Widget drawer(BuildContext context) {
    return Drawer(
child: ListView(
  padding: EdgeInsets.zero,
  children: <Widget>[
    Container(
        ...
    )
);

then your appbar.dart:

class CustomAppBar extends StatelessWidget implements PreferredSizeWidget {
  @override
  Widget build(BuildContext context) {
    return AppBar(
      backgroundColor: Colors.white,
      leading: InkWell(
        onTap: () => Scaffold.of(context).openDrawer(),
        child: Image.asset("assets/images/imgAppBar.png"),
      ),
     title: Container(...

then your index.dart:

@override
Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      drawer: drawer(context),
      appBar: CustomAppBar(),
    ...

this is just a simple one. You can use IconButton in case you want to use an Icon etc.

connelblaze
  • 779
  • 1
  • 10
  • 19
2

You need to create the Global key of type ScaffoldKey the use that to open the drawer and change the icon too:

    Widget build(BuildContext context) {
    var scaffoldKey = GlobalKey<ScaffoldState>();
    return Scaffold(
      key: scaffoldKey,
      appBar: AppBar(
        title:Text('hi'),
        leading: IconButton(
          icon: Icon(Icons.accessible),
          onPressed: () => scafoldKey.currentState.openDrawer(),
        ),
      ),
    );
Baker
  • 24,730
  • 11
  • 100
  • 106
Muhammad Naveed
  • 141
  • 1
  • 6
1
AppBar(
        leading: IconButton(
          onPressed: () {
            // Code
          },
          icon: Icon(Icons.arrow_back),
        ),
      ),
Masum Billah Sanjid
  • 1,029
  • 1
  • 7
  • 19
1

Actually, i tried the answer by cmd_prompter and it didn't work for me.

The better approach is described here

My working code is here:

return DefaultTabController(
      key: Key("homePage"),
      length: 2,
      child: Scaffold(
          endDrawer: Drawer(

        ),
          appBar: AppBar(
            leading: BackButton(
                onPressed: () {
                  },
              ),
            title: Text(profile.selectedCity!),
            actions: [
              Padding(
                padding: EdgeInsets.symmetric(horizontal: baseUnit(3)),
                child: Builder(
                  builder: (context) => IconButton(
                      icon: Icon(Icons.account_circle),
                      onPressed: () => Scaffold.of(context).openEndDrawer(),
                    )
                )
              )

It worked fine for me - especially this part regarding using Builder. This is important - otherwise it was not working for me.

Mike
  • 63
  • 1
  • 7
1
class HomeOne extends StatefulWidget { const HomeOne({Key? key}) : super(key: key);

@override State createState() =>HomeOneState(); }

var scaffoldKey = GlobalKey();

class HomeOneState extends State { @override Widget build(BuildContext context) { var theme = Theme.of(context); return Directionality( textDirection: TextDirection.rtl, child: Scaffold( key: scaffoldKey, drawerEnableOpenDragGesture: true, // drawerScrimColor: Colors.red, appBar: AppBar( leading: IconButton( onPressed: () => scaffoldKey.currentState?.openDrawer(), icon: const Icon( Icons.add, color: Colors.red, )), ),
Nimantha
  • 6,405
  • 6
  • 28
  • 69
AminFeizi
  • 31
  • 5
  • Code-only answers are not accepted. Please improve. Read https://stackoverflow.com/help/how-to-answer for information. – nurchi Nov 19 '21 at 17:05
0

To only change the icon color, it's easier to do by adding an iconTheme to the AppBar:

@override
Widget build(BuildContext context) {
  return Scaffold(
    drawer: Drawer(),
    appBar: AppBar(
      title: Text("Navigation Drawer"),
      iconTheme: IconThemeData(color: Colors.green),
    ),
  );
}
Nimantha
  • 6,405
  • 6
  • 28
  • 69
Rodrigo João Bertotti
  • 5,179
  • 2
  • 23
  • 34
0

Make an iconButton and wrap it with builder:

  Builder(
       builder: (context) {
           return IconButton(
              icon: const Icon(Icons.accessible),
              onPressed: () => Scaffold.of(context).openDrawer(),);
            }
          ),