7

I want to show a drawer when user clicks on the 4th(more_vert) icon, but I am not able to implement it. In my current implementation when 4th icon is clicked flutter takes me to a new page and there shows the drawer not over the current screen as it should. What am I doing wrong ? Also what is the differnce between BottomNavigationBar and BottomAppBar I could not find the difference anywhere. I checked out a few articles and it I think BottomAppBar is used to show the Fab floating in the bottom appbar. Is there any other difference between the two and when should one use one over the other.

class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  List<Widget> _widgetOptions = <Widget>[
    Page1(),
    Page2(),
    Page3(),
    Page4(),   // this page implements the drawer

  ];
  int _currentSelected = 0;

  void _onItemTapped(int index) {
    setState(() {
      _currentSelected = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: _widgetOptions.elementAt(_currentSelected),
      bottomNavigationBar: BottomNavigationBar(
        type: BottomNavigationBarType.fixed,
        onTap: _onItemTapped,
        currentIndex: _currentSelected,
        showUnselectedLabels: true,
        unselectedItemColor: Colors.grey[800],
        selectedItemColor: Color.fromRGBO(10, 135, 255, 1),
        items: <BottomNavigationBarItem>[
          BottomNavigationBarItem(
             icon: Icon(AntDesign.carryout),
          ),
          BottomNavigationBarItem(
             icon: Icon(MaterialCommunityIcons.sack),
          ),
          BottomNavigationBarItem(
             icon: Icon(Octicons.archive),
          ),
          BottomNavigationBarItem(
             icon: Icon(Icons.more_vert),
          )
        ],
      ),
      // backgroundColor: Colors.black,
    );
  }
}
sid597
  • 999
  • 3
  • 16
  • 31
  • 1
    have you just check checked this link which will help you out : https://stackoverflow.com/questions/56007613/how-to-programmatically-open-a-drawer-by-tapping-on-a-bottomnavigationbaritem – Sagar Acharya Feb 22 '20 at 17:49

3 Answers3

7

You don't need an extra page for that. You could do it like that:

class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  List<Widget> _widgetOptions = <Widget>[
    Page(),
    Page(),
    Page(),
  ];
  int _currentSelected = 0;
  GlobalKey<ScaffoldState> _drawerKey = GlobalKey();

  void _onItemTapped(int index) {
    index == 3
        ? _drawerKey.currentState.openDrawer()
        : setState(() {
            _currentSelected = index;
          });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: _drawerKey,
      body: _widgetOptions.elementAt(_currentSelected),
      drawer: Drawer(),
      bottomNavigationBar: BottomNavigationBar(
        type: BottomNavigationBarType.fixed,
        onTap: _onItemTapped,
        currentIndex: _currentSelected,
        showUnselectedLabels: true,
        unselectedItemColor: Colors.grey[800],
        selectedItemColor: Color.fromRGBO(10, 135, 255, 1),
        items: <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            title: Text('Page 1'),
            icon: Icon(Icons.access_alarm),
          ),
          BottomNavigationBarItem(
            title: Text('Page 2'),
            icon: Icon(Icons.accessible),
          ),
          BottomNavigationBarItem(
            title: Text('Page 3'),
            icon: Icon(Icons.adb),
          ),
          BottomNavigationBarItem(
            title: Text('Drawer'),
            icon: Icon(Icons.more_vert),
          )
        ],
      ),
    );
  }
}

class Page extends StatelessWidget {
  const Page({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container();
  }
}

Adding a GlobalKey for the Scaffold which implements the drawer and implementing the Drawer in your root Scaffold.

DennisSzymanski
  • 578
  • 4
  • 11
5

The BottomNavigationBar doesn't show the drawer icon like the AppBar does.

To open the drawer programmatically :

Create this variable as state :

GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey();

Set it as the Scaffold's key :

Scaffold(
      key: _scaffoldKey,

Then, you can use the key state to open the drawer :

_scaffoldKey.currentState.openDrawer();
MickaelHrndz
  • 3,604
  • 1
  • 13
  • 23
1

The solutions provided above work if you are not using the newer versions of Flutter with Null Safety. In case you are using Flutter 2.0 or greater. Due to Null Safety, you will get an error saying:

The method 'openDrawer' can't be unconditionally invoked because the receiver can be 'null'.
Try making the call conditional (using '?.') or adding a null check to the target 

Use: _drawerKey.currentState!.openDrawer();