0

I tried to extract my app bar and drawer into a separate stateless widgets (elrDrawer.dart). but when i click on the hamburger icon (in startUp.dart), the drawer opens behind the body. can somebody tell me why this is happening and how to solve it? appreciate the help <3

class Startup extends StatefulWidget {
  @override
  _StartupState createState() => _StartupState();
}

class _StartupState extends State<Startup> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: ElrDrawer(),
      drawer: ElrDrawer(),
      body: Container(
        color: Colors.pink,
        height: double.infinity,
        width: double.infinity,
        child: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              startUpCard('Order', Order()),
              startUpCard('History', History()),
              startUpCard('Menu', Menu()),
              startUpCard('FAQ', FAQ()),
            ],
          ),
        ),
      ),
    );
  }

^ startup.dart

Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        // automaticallyImplyLeading: false,
        title: Text('title'),
        actions: <Widget>[
          Padding(
            padding: EdgeInsets.all(10),
          ),
        ],
      ),
      drawer: Container(
        child: Drawer(
          child: ListView(
            children: [
              SizedBox(
                height: 300,
                child: DrawerHeader(
                  // padding: EdgeInsets.zero,
                  child: Stack(
                    alignment: Alignment.bottomLeft,
                    // fit: StackFit.passthrough,
                    children: [
                      Opacity(
                        opacity: 1,
                        child: Image.asset(
                          'assets/images/magik.png',
                        ),
                      ),
                    ],
                  ),
                ),
              ),
              drawerListTile(context, 'HISTORY', History()),
              divider(),
              drawerListTile(context, 'MENU', Menu()),
              divider(),
              drawerListTile(context, 'FAQ', FAQ()),
              divider(),
              drawerListTile(context, 'DASHBOARD', null),
              divider(),
              drawerListTile(context, 'LOGOUT', null),
              divider(),
            ],
          ),
        ),
      ),
      body: Container(
        color: Colors.brown,
      ),
    );
  }

^elrDrawer.dart

startUp.dart before click hamburger icon

startUp.dart after click hamburger icon with the drawer only appearing in the appBar

Marini MK
  • 49
  • 6

4 Answers4

3

You have nested Scaffold widgets inside the appBar and drawer property of your actual "main" Scaffold in your startup page.

Generally: try to make use of the Scaffold widgets only for widgets which actually represent a page / view and use more "primitive" / basic widgets for other parts of your view / widgets.

This could be a way to do that:

start_up.dart

class Startup extends StatefulWidget {
  @override
  _StartupState createState() => _StartupState();
}

class _StartupState extends State<Startup> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: ElrAppBar(),
      drawer: ElrDrawer(),
      body: Container(
        color: Colors.pink,
        height: double.infinity,
        width: double.infinity,
        child: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              startUpCard('Order', Order()),
              startUpCard('History', History()),
              startUpCard('Menu', Menu()),
              startUpCard('FAQ', FAQ()),
            ],
          ),
        ),
      ),
    );
  }

elr_app_bar.dart

/// The appBar property of Scaffold expects a Widget that
/// is from type PreferredSizeWidget, therefore you need to
/// implement it here to make it work (it only requires you to
/// override the preferredSize getter
class ElrAppBar extends StatelessWidget implements PreferredSizeWidget {
  const ElrAppBar({Key? key}) : super(key: key);

  @override
  Size get preferredSize => Size.fromHeight(kToolbarHeight);

  @override
  Widget build(BuildContext context) {
    return AppBar(
      // automaticallyImplyLeading: false,
      title: Text('title'),
      actions: <Widget>[
        Padding(
          padding: EdgeInsets.all(10),
        ),
      ],
    );
  }
}

elr_drawer.dart

class ElrDrawer extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Drawer(
      child: ListView(
        children: [
          SizedBox(
            height: 300,
            child: DrawerHeader(
              // padding: EdgeInsets.zero,
              child: Stack(
              alignment: Alignment.bottomLeft,
              // fit: StackFit.passthrough,
                children: [
                  Opacity(
                    opacity: 1,
                    child: Image.asset(
                      'assets/images/magik.png',
                    ),
                  ),
                ],
              ),
            ),
          ),
          drawerListTile(context, 'HISTORY', History()),
          divider(),
          drawerListTile(context, 'MENU', Menu()),
          divider(),
          drawerListTile(context, 'FAQ', FAQ()),
          divider(),
          drawerListTile(context, 'DASHBOARD', null),
          divider(),
          drawerListTile(context, 'LOGOUT', null),
          divider(),
        ],
      ),
    );
  }
kounex
  • 1,555
  • 4
  • 12
  • i seee.. thank you for your response sir! didn't think about that hmm.. nonetheless, is it okay if i directly ask you questions if i have anymore flutter enquiries? I'm still learning and I'm developing a flutter app at the moment.. – Marini MK Jul 15 '21 at 11:49
1

elrDrawer.dart shouldn't return a Scaffold, you should return only the Drawer widget wrapped or not in that container.

Radu Hrihoreanu
  • 364
  • 3
  • 16
1

As wonderful it is to split up the code into separate widgets, the mistake you're making is to think that the same class/widget would be able to function both as an appBar and drawer:

      appBar: ElrDrawer(),
      drawer: ElrDrawer(),

What you need to do is to create two separate widgets, like one that is responsible for making only a drawer:

class ElrDrawer extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Drawer(
      child: ListView(
        children: [
          SizedBox(
            height: 300,
            child: DrawerHeader(
              // padding: EdgeInsets.zero,
              child: Stack(
              alignment: Alignment.bottomLeft,
              // fit: StackFit.passthrough,
                children: [
                  Opacity(
                    opacity: 1,
                    child: Image.asset(
                      'assets/images/magik.png',
                    ),
                  ),
                ],
              ),
            ),
          ),
          drawerListTile(context, 'HISTORY', History()),
          divider(),
          drawerListTile(context, 'MENU', Menu()),
          divider(),
          drawerListTile(context, 'FAQ', FAQ()),
          divider(),
          drawerListTile(context, 'DASHBOARD', null),
          divider(),
          drawerListTile(context, 'LOGOUT', null),
          divider(),
        ],
      ),
    );
}

And another which is responsible for an AppBar:

https://stackoverflow.com/a/54355656/11218270

happy-san
  • 810
  • 1
  • 7
  • 27
  • 1
    i tried to seperate them at first but sadly, i just couldn't find the problem causing it so i tried to combine them. apologise for my noob coding skills but thank you for your response! :D – Marini MK Jul 15 '21 at 11:47
1

1- You shouldn't use the same widget as a drawer and an appbar. These widgets plays completely different roles so they can't be the same. For the appbar, just add a title as a child and actions (like what you did in elrDrawer.dart), like this :

class Startup extends StatefulWidget {
  @override
  _StartupState createState() => _StartupState();
}

class _StartupState extends State<Startup> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        // automaticallyImplyLeading: false,
        title: Text('title'),
        actions: <Widget>[
          Padding(
            padding: EdgeInsets.all(10),
          ),
        ],
      ),
      drawer: ElrDrawer(),
      body: Container(
        color: Colors.pink,
        height: double.infinity,
        width: double.infinity,
        child: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              startUpCard('Order', Order()),
              startUpCard('History', History()),
              startUpCard('Menu', Menu()),
              startUpCard('FAQ', FAQ()),
            ],
          ),
        ),
      ),
    );
  }

^ startup.dart

2- Your drawer shouldn't return a scaffold, and this what is creates the problem. Just return a Drawer or a Container that contains a Drawer, like this :

Widget build(BuildContext context) {
    return Container(
        child: Drawer(
          child: ListView(
            children: [
              SizedBox(
                height: 300,
                child: DrawerHeader(
                  // padding: EdgeInsets.zero,
                  child: Stack(
                    alignment: Alignment.bottomLeft,
                    // fit: StackFit.passthrough,
                    children: [
                      Opacity(
                        opacity: 1,
                        child: Image.asset(
                          'assets/images/magik.png',
                        ),
                      ),
                    ],
                  ),
                ),
              ),
              drawerListTile(context, 'HISTORY', History()),
              divider(),
              drawerListTile(context, 'MENU', Menu()),
              divider(),
              drawerListTile(context, 'FAQ', FAQ()),
              divider(),
              drawerListTile(context, 'DASHBOARD', null),
              divider(),
              drawerListTile(context, 'LOGOUT', null),
              divider(),
            ],
          ),
        ),
      ),
      body: Container(
        color: Colors.brown,
      ),
    );
  }


^elrDrawer.dart

Everything should look fine after that.