将密钥传递给 child 时无法正常工作 |扑

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

所以我的脚手架中有一把脚手架钥匙:

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

在我的脚手架中,我有一个自定义抽屉和一个自定义应用栏:

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

我将打开抽屉功能传递给自定义AppBar。我的自定义 AppBar 接受这样的功能:

 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,
          ),
        ),

问题是抽屉从一开始就打不开。当我通过点击我的底部栏(下面的代码)切换我的屏幕主体时,抽屉打开。我猜我的钥匙在我第一次加载应用程序时有一个空值,因此抽屉没有打开。如果是这种情况,我需要为键设置一个默认值。完整代码如下。


这是完整的代码,也许它比简化的代码更相关:

我创建密钥的 class 如下所示:

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,
        ),
      ),
    );
  }
}

如上所示,我将密钥传递给 StartAppBar,如下所示:

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)),
        ],
      ),
    );
  }
}

有什么办法可以解决这个问题吗?

您不必创建一个GlobalKey,您只需这样写:

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

因为在你的widget树中,你已经只有一个Scaffold,所以你不需要用key让它唯一,所以你的IconButton知道打开哪个Scaffold和Drawer。

现在剩下的就是删除 void Function()?打开抽屉;