I am trying to open a drawer on the press of an icon, inside of a sticky header I have created in a flutter app

83 views Asked by At

So I created a sticky header that goes from page to page and I really like the design.

App header

I am trying to make the hamburger icon on the left open a drawer. Below is my class widget. I have tried: onpress: () {Scaffold.of(context).openDrawer();},

I have tried turning the Container into a Scaffold, I can't keep its appearance when I make it a scaffold, and I have tried making a GlobalKey. But every where I find says that it needs to be a Scaffold for the Global key to work. is there anyway I could make a Scaffold inside of this Container because I tried to put the Container in a Scaffold and that didn't work either.

Also my main.dart imports the file this is made on and then calls the class inside the MyApp class. Thanks for the help.

class HeaderWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.all(8.0),
      color: headerBackGroundColor,
      alignment: Alignment.center,
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        children: <Widget>[
          // Menu icon
          IconButton(
            iconSize: 24,
            icon: const Icon(
              Icons.menu,
              color: headerMenuIconColor,
              semanticLabel: 'Main menu for navigating app.',
            ),
            onPressed: () {
              ScaffoldMessenger.of(context).showSnackBar(
                  SnackBar(content: Text('Menu icon button was pressed')));
            },
            tooltip: "Select an option from the menu.",
          ),
          // Search icon
          IconButton(
            iconSize: 24,
            icon: const Icon(
              Icons.search,
              color: headerSearchIconColor,
              semanticLabel: 'Search the app.',
            ),
            onPressed: () {
              ScaffoldMessenger.of(context).showSnackBar(
                  SnackBar(content: Text('Search icon button was pressed')));
            },
            tooltip: "Enter a search term.",
          ),
          // Share icon
          IconButton(
            iconSize: 24,
            icon: const Icon(
              Icons.share,
              color: headerShareIconColor,
              semanticLabel: 'Share this page from the app.',
            ),
            onPressed: () {
              ScaffoldMessenger.of(context).showSnackBar(
                  SnackBar(content: Text('Share icon button was pressed')));
            },
            tooltip: "Share this content.",
          ),
          // Weather icon
          IconButton(
            iconSize: 24,
            icon: const Icon(
              Icons.cloud,
              color: headerWeatherIconColor,
              semanticLabel:
                  'Weather widget with temperature and sky conditions.',
            ),
            onPressed: () {
              ScaffoldMessenger.of(context).showSnackBar(
                  SnackBar(content: Text('Weather icon button was pressed')));
            },
            tooltip: "Set weather options.",
          ),
        ],
      ),
    );
  }
}

EDIT: I guess I am doing something wrong. The following is my header.dart:

import 'package:flutter/material.dart';
import 'app_config.dart';

final scaffoldKey = GlobalKey<ScaffoldState>();

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: scaffoldKey,
      appBar: PreferredSize(
        preferredSize: const Size.fromHeight(kToolbarHeight),
        child: HeaderWidget(),
      ),
      drawer: const Drawer(child: Center(child: Text('Drawer'))),
      body: const Center(child: Text('Example Page')),
    );
  }
}

class HeaderWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.all(8.0),
      color: headerBackGroundColor,
      alignment: Alignment.center,
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        children: <Widget>[
          // Menu icon
          IconButton(
            iconSize: 24,
            icon: const Icon(
              Icons.menu,
              color: headerMenuIconColor,
              semanticLabel: 'Main menu for navigating app.',
            ),
            onPressed: () {
              scaffoldKey.currentState!.openDrawer();

            },
            tooltip: "Select an option from the menu.",
          ),
          // Search icon
          IconButton(
            iconSize: 24,
            icon: const Icon(
              Icons.search,
              color: headerSearchIconColor,
              semanticLabel: 'Search the app.',
            ),
            onPressed: () {
              ScaffoldMessenger.of(context).showSnackBar(
                  SnackBar(content: Text('Search icon button was pressed')));
            },
            tooltip: "Enter a search term.",
          ),
          // Share icon
          IconButton(
            iconSize: 24,
            icon: const Icon(
              Icons.share,
              color: headerShareIconColor,
              semanticLabel: 'Share this page from the app.',
            ),
            onPressed: () {
              ScaffoldMessenger.of(context).showSnackBar(
                  SnackBar(content: Text('Share icon button was pressed')));
            },
            tooltip: "Share this content.",
          ),
          // Weather icon
          IconButton(
            iconSize: 24,
            icon: const Icon(
              Icons.cloud,
              color: headerWeatherIconColor,
              semanticLabel:
                  'Weather widget with temperature and sky conditions.',
            ),
            onPressed: () {
              ScaffoldMessenger.of(context).showSnackBar(
                  SnackBar(content: Text('Weather icon button was pressed')));
            },
            tooltip: "Set weather options.",
          ),
        ],
      ),
    );
  }
}

Then I call it in my main.dart

import 'header.dart';

class MyHomePage extends StatelessWidget {
  const MyHomePage(
      {super.key, required this.bootStrapInfo, required this.myAppDefines});
  final BootStrapInfo bootStrapInfo;
  final AppDefines myAppDefines;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(AppConfig.appName),
        ),
        body: Center(
          child: Column(
            children: [
              HeaderWidget(),
              SplashWidget(),
              // Body Container
              Expanded(
                child: SingleChildScrollView(

I can not get a key to work at all. Please help!

1

There are 1 answers

7
Cabdirashiid On

Try using a global key

Declare a scaffold state global key:

final scaffoldKey = GlobalKey<ScaffoldState>();

Assign it to a scaffold, must have a drawer set as well:

...

Scaffold(
  key: scaffoldKey,
  drawer: Drawer(),

...

Open it like so:

scaffoldKey.currentState!.openDrawer();

Full example with HeaderWidget in question

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: Page(),
    );
  }
}

final scaffoldKey = GlobalKey<ScaffoldState>();

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: scaffoldKey,
      appBar: const PreferredSize(
        preferredSize: Size.fromHeight(kToolbarHeight),
        child: HeaderWidget(),
      ),
      drawer: const Drawer(child: Center(child: Text('Drawer'))),
      body: const Center(child: Text('Example Page')),
    );
  }
}

class HeaderWidget extends StatelessWidget {
  const HeaderWidget({super.key});

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.all(8.0),
      color: headerBackGroundColor,
      alignment: Alignment.center,
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        children: <Widget>[
          // Menu icon
          IconButton(
            iconSize: 24,
            icon: const Icon(
              Icons.menu,
              color: headerMenuIconColor,
              semanticLabel: 'Main menu for navigating app.',
            ),
            onPressed: () {
              scaffoldKey.currentState!.openDrawer();
            },
            tooltip: "Select an option from the menu.",
          ),
          // Search icon
          IconButton(
            iconSize: 24,
            icon: const Icon(
              Icons.search,
              color: headerSearchIconColor,
              semanticLabel: 'Search the app.',
            ),
            onPressed: () {
              ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
                  content: Text('Search icon button was pressed')));
            },
            tooltip: "Enter a search term.",
          ),
          // Share icon
          IconButton(
            iconSize: 24,
            icon: const Icon(
              Icons.share,
              color: headerShareIconColor,
              semanticLabel: 'Share this page from the app.',
            ),
            onPressed: () {
              ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
                  content: Text('Share icon button was pressed')));
            },
            tooltip: "Share this content.",
          ),
          // Weather icon
          IconButton(
            iconSize: 24,
            icon: const Icon(
              Icons.cloud,
              color: headerWeatherIconColor,
              semanticLabel:
                  'Weather widget with temperature and sky conditions.',
            ),
            onPressed: () {
              ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
                  content: Text('Weather icon button was pressed')));
            },
            tooltip: "Set weather options.",
          ),
        ],
      ),
    );
  }
}

Try this:

Example using a custom scaffold page as parent

my_scaffold.dart

import 'package:flutter/material.dart';

import 'header_widget.dart';

final _scaffoldKey = GlobalKey<ScaffoldState>();

class MyScaffold extends StatelessWidget {
  final Widget body;
  const MyScaffold({super.key, required this.body});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: _scaffoldKey,
      drawer: const Drawer(child: Center(child: Text('Drawer'))),
      appBar: PreferredSize(
        preferredSize: const Size.fromHeight(kToolbarHeight),
        child: HeaderWidget(scaffoldKey: _scaffoldKey),
      ),
      body: body,
    );
  }
}

header_widget.dart

import 'package:flutter/material.dart';

class HeaderWidget extends StatelessWidget {
  final GlobalKey<ScaffoldState> scaffoldKey;

  const HeaderWidget({
    super.key,
    required this.scaffoldKey,
  });

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.all(8.0),
      color: headerBackGroundColor,
      alignment: Alignment.center,
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        children: <Widget>[
          // Menu icon
          IconButton(
            iconSize: 24,
            icon: const Icon(
              Icons.menu,
              color: headerMenuIconColor,
              semanticLabel: 'Main menu for navigating app.',
            ),
            onPressed: () {
              scaffoldKey.currentState!.openDrawer();
            },
            tooltip: "Select an option from the menu.",
          ),
          // Search icon
          IconButton(
            iconSize: 24,
            icon: const Icon(
              Icons.search,
              color: headerSearchIconColor,
              semanticLabel: 'Search the app.',
            ),
            onPressed: () {
              ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
                  content: Text('Search icon button was pressed')));
            },
            tooltip: "Enter a search term.",
          ),
          // Share icon
          IconButton(
            iconSize: 24,
            icon: const Icon(
              Icons.share,
              color: headerShareIconColor,
              semanticLabel: 'Share this page from the app.',
            ),
            onPressed: () {
              ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
                  content: Text('Share icon button was pressed')));
            },
            tooltip: "Share this content.",
          ),
          // Weather icon
          IconButton(
            iconSize: 24,
            icon: const Icon(
              Icons.cloud,
              color: headerWeatherIconColor,
              semanticLabel:
                  'Weather widget with temperature and sky conditions.',
            ),
            onPressed: () {
              ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
                  content: Text('Weather icon button was pressed')));
            },
            tooltip: "Set weather options.",
          ),
        ],
      ),
    );
  }
}

MyHomePage should look like this:

// import my_scaffold.dart

class MyHomePage extends StatelessWidget {
  const MyHomePage({
    super.key,
    required this.bootStrapInfo,
    required this.myAppDefines,
  });

  final BootStrapInfo bootStrapInfo;
  final AppDefines myAppDefines;

  @override
  Widget build(BuildContext context) {
    return MyScaffold(
      body: Center(
        child: Column(
          children: [
              SplashWidget(),
              // Body Container
          ],
        ),
      ),
    );
  }
}