Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Key doesn't work properly when passing it on to child | Flutter

So I have a Scaffold Key in my Scaffold:

final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();

And in my Scaffold I have a custom Drawer and a custom App Bar:

Scaffold(
    key: _scaffoldKey,
    backgroundColor: Color(0xFF3FC1C9),
    drawer: HomeDrawer(),
    body: StartAppBar(_scaffoldKey.currentState?.openDrawer),
  ),

Im passing the open Drawer function on to the custom AppBar. My custom AppBar accepts the function like this:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

 class StartAppBar extends StatelessWidget {
      void Function()? openDrawer;
      StartAppBar(this.openDrawer);
    and references it here:
    
        leading: IconButton(
          onPressed: () {
            openDrawer!();
            // _key.currentState!.openEndDrawer();
          },
          icon: Icon(
            Icons.view_headline_rounded,
          ),
        ),

The problem is that the drawer doesn’t open from the start on. When I switch the bodies of my Screen though through clicking on my bottom bar that I have (code below) the drawer opens. Im guessing that my key has a null value when I load the app for the first time, as a consequence the drawer doesn’t open. If that would be the case I would need to set a default value for the key. The whole code is below.


This is the whole code, perhaps it is more relevant then the simplified one:

My class where I create the key looks like this:

class HomeScreen extends StatefulWidget {
  final marken;
  const HomeScreen({Key? key, this.marken}) : super(key: key);
  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  late List<Widget> _widgetOptions;

  @override
  initState() {
    _widgetOptions = <Widget>[
      Favorites(),
      BodyHomeScreen(
        marken: widget.marken,
      ),
      Kontakt(),
    ];
  }

  DateTime? lastPressed;
  final HideNavbar hiding = HideNavbar();
  int _selectedIndex = 1;

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

  final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () => FocusManager.instance.primaryFocus?.unfocus(),
      child: Scaffold(
        key: _scaffoldKey,
        backgroundColor: Color(0xFF3FC1C9),
        drawer: HomeDrawer(),
        body: StartAppBar(_selectedIndex, hiding, lastPressed, _widgetOptions,
            _scaffoldKey.currentState?.openDrawer),
        bottomNavigationBar: BottomBar(
          _onItemTap,
          _selectedIndex,
          hiding,
        ),
      ),
    );
  }
}

As also seen above im passing the key on to the StartAppBar, that looks like this:

import 'package:flutter/material.dart';

class StartAppBar extends StatelessWidget {
  final int selectedIndex;
  final hiding;
  List<Widget> widgetOptions;
  var lastPressed;
  void Function()? openDrawer;
  StartAppBar(this.selectedIndex, this.hiding, this.lastPressed,
      this.widgetOptions, this.openDrawer);

  @override
  Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: () async {
        final now = DateTime.now();
        final maxDuration = Duration(seconds: 2);
        final isWarning =
            lastPressed == null || now.difference(lastPressed!) > maxDuration;

        if (isWarning) {
          lastPressed = DateTime.now();

          final snackBar = SnackBar(
            content: Container(
              //color: Colors.white,
              decoration: BoxDecoration(
                  color: Color(0xFF03DAC6),
                  borderRadius: BorderRadius.circular(20)),
              margin: EdgeInsets.fromLTRB(0, 0, 0, 20),
              child: Padding(
                padding: const EdgeInsets.all(8.0),
                child: Text(
                  'Doppelklick zum verlassen',
                  textAlign: TextAlign.center,
                ),
              ),
            ),
            backgroundColor: Colors.transparent,
            elevation: 1000,
            behavior: SnackBarBehavior.floating,
            duration: maxDuration,
          );

          ScaffoldMessenger.of(context)
            ..removeCurrentSnackBar()
            ..showSnackBar(snackBar);

          return false;
        } else {
          return true;
        }
      },
      child: CustomScrollView(
        controller: hiding.controller,
        slivers: [
          SliverAppBar(
            backgroundColor: Color(0xFF3FC1C9),
            automaticallyImplyLeading: false,
            elevation: 0,
            title: Text(
              "AutoLab",
              style:
                  TextStyle(color: Colors.white, fontWeight: FontWeight.bold),
            ),
            leading: IconButton(
              onPressed: () {
                openDrawer?.call();
                // _key.currentState!.openEndDrawer();
              },
              icon: Icon(
                Icons.view_headline_rounded,
              ),
            ),
            centerTitle: true,
            expandedHeight: 120,
            floating: false,
            flexibleSpace: FlexibleSpaceBar(
              title: selectedIndex == 1
                  ? Text("Marke auswählen")
                  : selectedIndex == 2
                      ? Text("Schreibe uns!")
                      : Text("Deine Modelle"),
              centerTitle: true,
            ),
          ),
          SliverToBoxAdapter(child: widgetOptions.elementAt(selectedIndex)),
        ],
      ),
    );
  }
}

Any ideas how I can fix this behaviour?

>Solution :

It’s not necessary that you create a GlobalKey, you only write this :

onPressed: () {
    Scaffold.of(context).openDrawer();
},

Because in your widget tree, you already have only one Scaffold, so you don’t need to make it unique with a key, so your IconButton knows which Scaffold and Drawer to open.

And now all that remains is to remove the void Function()? openDrawer;

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading