首页 > 解决方案 > Flutter 从不同的 dart 文件访问父 Scaffold

问题描述

我有这个:

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

  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: 2,
      child: Scaffold(
        key: _scaffoldkey,
        drawer: Menu(),
        appBar: AppBar(
          title: Container(
            child: Text('Dashboard'),
          ),
          bottom: TabBar(
            tabs: <Widget>[
              ...
            ],
          ),
        ),
        body: TabBarView(
          children: <Widget>[
            ...
          ],
        ),
      ),
    );
  }
}

现在,drawer: Menu()从另一个menu.dart文件导入,如下所示:

class Menu extends StatelessWidget {

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

  @override
  Widget build(BuildContext context) {
    return new Drawer(
      key: drawerKey,
      child: new ListView(
        children: <Widget>[
          new ListTile(
            dense: true,
            title: new Text('My Text'),
            onTap: () {
              // On tap this, I want to show a snackbar.
              scaffoldKey.currentState.showSnackBar(showSnack('Error. Could not log out'));
            },
          ),
        ],
      ),
    );
  }
}

通过上述方法,我得到

NoSuchMethodError: The method 'showSnackBar' was called on null.

一个简单的解决方案是将整个menu.dart内容drawer: ...直接塞入。

我正在研究的另一种方式是能够引用父脚手架以显示小吃栏。

怎么能做到这一点?

为什么甚至不能从 Flutter 的任何地方调用小吃店,并且必须通过 Scaffold 来完成?只是为什么?

标签: dartflutter

解决方案


你应该尽量避免使用GlobalKey;使用Scaffold.ofScaffoldState 几乎总是更好。由于您的菜单位于小部件树中的脚手架下方,Scaffold.of(context)因此可以执行您想要的操作。

您尝试做的事情不起作用的原因是您正在创建两个单独的 GlobalKeys - 每个都是它自己的对象。将它们视为全局指针 - 因为您正在创建两个不同的指针,它们指向不同的东西。由于您将错误的类型传递到抽屉的key字段中,因此状态应该确实失败了分析...

如果您出于某种原因绝对必须使用 GlobalKeys,最好将在外部小部件中创建的实例Menu作为成员 ie 传递到您的类中this.scaffoldKey,但不建议这样做。

使用Scaffold.of,这就是您的代码在 onTap 函数中的样子:

onTap: () {
  // On tap this, I want to show a snackbar.
  Scaffold.of(context).showSnackBar(showSnack('Error. Could not log out'));
},

推荐阅读