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

Time:05-06

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:

 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?

CodePudding user response:

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;

  • Related