Flutter: how to make Drawer z-index on top of all widget with Layout builder?

1.3k views Asked by At

I'm building a responsive flutter app. i use layout builder to achieve that. I also need to open a drawer on my screen. Then I faced the problem that the second screen was piling up on top of my drawer. i need a drawer to appear above all my widgets. Is there a workaround to achieve this with a layout builder?

if you want to try ,you can clone this repository: Flutter responsive drawer

preview:

enter image description here

i want the drawer show up on top of all page.

here some summary code (full code you can check on github link ) 1:

main_screen.dart

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Responsive(
        mobile: Column(
          children: const [Expanded(child: Page1()), Expanded(child: Page2())],
        ),
        tablet: Row(
          children: const [
            Expanded(flex: 1, child: Page1()),
            Expanded(flex: 2, child: Page2())
          ],
        ),
        desktop: Row(
          children: const [Expanded(child: Page1()), Expanded(child: Page2())],
        ),
      ),
    );
  }
}

page1.dart

class Page1 extends StatefulWidget {
  const Page1({Key? key}) : super(key: key);

  @override
  State<Page1> createState() => _Page1State();
}

class _Page1State extends State<Page1> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      drawer: const MyDrawer(),
      body: Container(
        alignment: Alignment.center,
        color: Colors.blue,
        child: const Text("Page 1"),
      ),
    );
  }
}

page2.dart

class Page2 extends StatefulWidget {
  const Page2({Key? key}) : super(key: key);

  @override
  State<Page2> createState() => _Page2State();
}

class _Page2State extends State<Page2> {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.green,
      alignment: Alignment.center,
      child: const SafeArea(
        child: Text("Page 2"),
      ),
    );
  }
}

responsive.dart

class Responsive extends StatelessWidget {
  final Widget mobile;
  final Widget tablet;
  final Widget desktop;
  const Responsive({
    Key? key,
    required this.desktop,
    required this.mobile,
    required this.tablet,
  }) : super(key: key);

  /// mobile < 650
  static bool isMobile(BuildContext context) =>
      MediaQuery.of(context).size.width < 650;

  /// tablet >= 650
  static bool isTablet(BuildContext context) =>
      MediaQuery.of(context).size.width >= 650;

  ///desktop >= 1100
  static bool isDesktop(BuildContext context) =>
      MediaQuery.of(context).size.width >= 1500;

  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(builder: (context, constraints) {
      if (constraints.maxWidth >= 1500) {
        return desktop;
      } else if (constraints.maxWidth >= 650) {
        return tablet;
      } else {
        return mobile;
      }
    });
  }
}
2

There are 2 answers

0
pmatatias On BEST ANSWER

as mentioned @Mohamed Reda, by put the drawer on main screen to make it on top all widget. Then to make access the drawer button are using scaffoldKey.

class MainScreen extends StatelessWidget {
  MainScreen({Key? key}) : super(key: key);
  final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      drawer: const MyDrawer(),
      key: _scaffoldKey,
      body: SafeArea(
        child: Responsive(
          mobile: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              IconButton(
                icon: const Icon(Icons.menu),
                onPressed: () {
                  _scaffoldKey.currentState?.openDrawer();
                },
              ),
              const Expanded(child: Page1()),
              const Expanded(child: Page2())
            ],
          ),
          tablet: Row(
            children: [
              Expanded(
                  flex: 1,
                  child: Column(
                    children: [
                      IconButton(
                        icon: const Icon(Icons.menu),
                        onPressed: () {
                          _scaffoldKey.currentState?.openDrawer();
                        },
                      ),
                      const SizedBox(
                        width: 10,
                      ),
                      const Page1(),
                    ],
                  )),
              const Expanded(flex: 2, child: Page2())
            ],
          ),
          desktop: Row(
            children: [
              Expanded(
                  child: Column(
                children: [
                  IconButton(
                    icon: const Icon(Icons.menu),
                    onPressed: () {
                      _scaffoldKey.currentState?.openDrawer();
                    },
                  ),
                  const SizedBox(
                    width: 10,
                  ),
                  const Page1(),
                ],
              )),
              const Expanded(child: Page2())
            ],
          ),
        ),
      ),
    );
  }
}
2
Mohamed Reda On

These are the wrong parts of the code:

  1. you put the drawer at the wrong page, you put it for just the first page like this

    @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(),
          drawer: const MyDrawer(),
          body: Container(
            alignment: Alignment.center,
            color: Colors.blue,
            child: const Text("Page 1"),
          ),
        );
      }
    }
    

so, you should delete the drawer from here and put it at the main_screen.dart

  1. do the same last step for the appBar and put it at main_screen.dart
  2. It's recommended for Any screen to have one Scaffold widget and you have it at main_screen.dart, so delete it from page1 to make it like page2

I hope that solved your problem.