5

I have a simple drawer in Flutter project and I want to make the drawer to be always above bottom navigation bar when ever the user slide/open. I play around with my code but can't find any solution yet.

     import 'package:flutter/material.dart';
import 'package:testing2/pages/ChannelsPage.dart';
import 'package:testing2/pages/HomePage.dart';
import 'package:testing2/pages/ExplorePage.dart';
import 'package:testing2/fragments/first_fragment.dart';
import 'package:testing2/fragments/second_fragment.dart';
import 'package:testing2/fragments/third_fragment.dart';
import 'package:testing2/Shared/drawer.dart';

class MyHomePage extends StatefulWidget {

  @override
  _MyBottomNavigationBarState createState() => _MyBottomNavigationBarState();
}

class _MyBottomNavigationBarState extends State<MyHomePage> {
  final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
  int _currentSelected = 0;
  GlobalKey<ScaffoldState> _drawerKey = GlobalKey<ScaffoldState>();
  final List<Widget> _children = [
    HomePage(),
    SettingsPage(),
    ContactPage(),
    HomePage()
  ];

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

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      key: _drawerKey,
      drawer: new Drawer(
        child: ListView(
          children: <Widget>[
            new DrawerHeader(
              child: new Text('Jonathan'),
              decoration: new BoxDecoration(color: Colors.orange),),
              new ListTile(
                leading: const Icon(Icons.notifications),
                title: new Text('Notifications'),
                onTap: (){
                  Navigator.pop(context);
                  Navigator.push(context, new MaterialPageRoute(builder: (context) => new FirstFragment()));
                },
              ),
              new ListTile(
                leading: const Icon(Icons.list),
                title: new Text('Preferences'),
                onTap: (){
                  Navigator.pop(context);
                  Navigator.push(context, new MaterialPageRoute(builder: (context) => new SecondFragment()));
                },
              ),
              new ListTile(
                leading: const Icon(Icons.help),
                title: new Text('Help'),
                onTap: (){
                  Navigator.pop(context);
                  Navigator.push(context, new MaterialPageRoute(builder: (context) => new ThirdFragment()));
                },
              ),
              new ListTile(
                leading: const Icon(Icons.outlined_flag),
                title: new Text('Logout'),
                onTap: (){
                  Navigator.pop(context);
                  Navigator.push(context, new MaterialPageRoute(builder: (context) => new FirstFragment()));
                },
              ),
          ],
        )
      ),
      body:_children[_currentSelected],
      bottomNavigationBar: BottomNavigationBar(
        backgroundColor: Colors.blueGrey[900],  
        type: BottomNavigationBarType.fixed,
        onTap: onTappedBar,
        currentIndex: _currentSelected,
        showUnselectedLabels: true,
        unselectedItemColor: Colors.white,
        selectedItemColor: Color.fromRGBO(10, 135, 255, 1),
        items: <BottomNavigationBarItem> [ 
          BottomNavigationBarItem(icon: new Icon(Icons.home), title: new Text('Home')),
          BottomNavigationBarItem(icon: new Icon(Icons.search), title: new Text('Explore')),
          BottomNavigationBarItem(icon: new Icon(Icons.device_hub), title: new Text('Channels')),
          BottomNavigationBarItem(icon: new Icon(Icons.dehaze), title: new Text('More')),
        ],
      ),     
    );
  }
}
class Page extends StatelessWidget {
  const Page({Key key}) : super(key: key);

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

enter image description here

I did the way you told me and the drawer is above the bottom navigation bar but the 4th icon to open the drawer is not working anymore.

2 Answers2

2

You can Do this in following way.

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key}) : super(key: key);

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _selectedIndex = 0;
  static const TextStyle optionStyle =
      TextStyle(fontSize: 30, fontWeight: FontWeight.bold);
  static const List<Widget> _widgetOptions = <Widget>[
    Text(
      'Index 0: Home',
      style: optionStyle,
    ),
    Text(
      'Index 1: Business',
      style: optionStyle,
    ),
    Text(
      'Index 2: School',
      style: optionStyle,
    ),
  ];

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Scaffold(
        body: Center(
          child: _widgetOptions.elementAt(_selectedIndex),
        ),
        appBar: AppBar(
          title: Text("data"),
        ),
        drawer: Drawer(
          child: Center(
            child: RaisedButton(
              child: Text("Press"),
              onPressed: () {
                Navigator.push(
                    context, MaterialPageRoute(builder: (context) => Hello1()));
              },
            ),
          ),
        ),
      ),
      bottomNavigationBar: BottomNavigationBar(
        items: const <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: Icon(Icons.home),
            title: Text('Home'),
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.business),
            title: Text('Business'),
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.school),
            title: Text('School'),
          ),
        ],
        currentIndex: _selectedIndex,
        selectedItemColor: Colors.amber[800],
        onTap: _onItemTapped,
      ),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        child: Center(
          child: Text("data"),
        ),
      ),
    );
  }
}
Viren V Varasadiya
  • 25,492
  • 9
  • 45
  • 61
  • Thanks Viren, it work but I can't navigate to different page anymore. for body I have like this, body: _children[_currentSelected] which _children is a List that contain different pages and it navigate them. do you know what I can do to fix it. thanks –  Apr 15 '20 at 17:10
  • 1
    i didn't understand you exactly but i change my answer code checkout does it answer your question or not? – Viren V Varasadiya Apr 15 '20 at 17:22
  • Hi Viren..It was working but the only problem I have is the 4th icon on bottom navigation bar does not open the drawer anymore. My goal is to make the drawer above bottom navigation bar and also use the 4th icon in bottom navigation bar to open the drawer. I just added my original code if you don't mind checking it out. –  Apr 16 '20 at 01:25
  • 1
    it is working completely fine. give it full restart may it work for you. – Viren V Varasadiya Apr 16 '20 at 04:56
  • @VirenVVarasadiya if one of your pages was to be set with a Google map rather than static text, how could you implement this? When I try to add to static const List _widgetOptions = , I get 'only static members can be accessed in initializers', I will look at this more later. Following this tutorial and flutter docs: https://willowtreeapps.com/ideas/how-to-use-flutter-to-build-an-app-with-bottom-navigation – William Humphries Jun 04 '20 at 01:36
  • It is clearly saying that you are using variable in initialisation which is not static. Put your that code in initState it will work. – Viren V Varasadiya Jun 04 '20 at 01:40
1

@Aase Zi, you can pass your _MyBottomNavigationBarState key, in a child page in make this

widget.globalScaffoldKey.currentState.openDrawer();

globalScaffoldKey is the name of my variable in my case.