带有 Scaffold 的 InheritedWidget 似乎无法正常工作

Posted

技术标签:

【中文标题】带有 Scaffold 的 InheritedWidget 似乎无法正常工作【英文标题】:InheritedWidget with Scaffold as child doesn't seem to be working 【发布时间】:2018-08-28 15:37:35 【问题描述】:

我希望在我的 Flutter 应用程序的根级别使用 InheritedWidget,以确保所有子小部件都可以使用经过身份验证的用户的详细信息。基本上让 Scaffold 成为 IW 的子节点,如下所示:

@override
Widget build(BuildContext context) 
return new AuthenticatedWidget(
    user: _user,
    child: new Scaffold(
      appBar: new AppBar(
        title: 'My App',
      ),
      body: new MyHome(),
      drawer: new MyDrawer(),
    ));

这在应用程序启动时按预期工作,因此在表面上 似乎 我已经在我的 AuthenticatedWidget 中正确实现了 InheritedWidget 模式,但是当我从其他地方返回主页 (MyHome) 时这个:

Navigator.popAndPushNamed(context, '/home');

这个调用 MyHome 的 build 方法(之前有效)然后导致 authWidget 为空:

final authWidget = AuthenticatedWidget.of(context);

完全有可能我错过了如何正确实施 IW 的一些细微差别,但同样,它最初确实有效,而且我也看到其他人提出了同样的问题(即“继承的小部件”标题下的 here)。

因此不能使用 Scaffold 或 MaterialApp 作为 InheritedWidget 的子级吗?或者这可能是一个要提出的错误?提前致谢!

【问题讨论】:

【参考方案1】:

MyInherited.of(context) 基本上会查看 当前上下文 的父级以查看是否有 MyInherited 实例化。

问题是:您继承的小部件是在当前上下文中中实例化的。

=> 没有MyInherited 作为父母

=> 崩溃

诀窍是使用不同的上下文。 那里有很多解决方案。您可以在另一个小部件中实例化MyInherited,这样您的构建方法的context 就会有一个MyInherited 作为父级。

或者您可能会使用Builder 来引入一个假小部件,该小部件将向您传递它的上下文。

构建器示例:

return new MyInheritedWidget(
  child: new Builder(
    builder: (context) => new Scaffold(),
  ),
);

另一个问题,出于同样的原因,如果你在一个路由inside插入一个inheritedWidget,它在这个路由的outside将不可用。

这里的解决方案很简单! 把你的MyInheritedWidget 放在上面 MaterialApp.

以上材料:

new MyInherited(
  child: new MaterialApp(
    // ...
  ),
)

【讨论】:

非常感谢@Darky!这里有一些很棒的见解。对我来说,这里的困惑仍然是它确实在第一次运行而不是在以后的导航之后工作。如果我的父母/当前的事情错了,我们根本不会期望它起作用,是吗? here 提出了一个有趣的观点,上面写着 ...当您使用 Navigator.push 显示这些页面时,它们不会继承带有父上下文的小部件。 这似乎确实指出了我的问题,并且很可能和你说的也有关系,我会继续挖掘。再次感谢。 导航器路线彼此无关。他们有相同的基础:MaterialApp 和它的父母。但就是这样。 @KBDrums,如果这是您要找的,请随时接受 Darky 的回答【参考方案2】:

因此不能使用 Scaffold 或 MaterialApp 作为 InheritedWidget 的子级?

这是很有可能做到的。我早些时候为此苦苦挣扎,并发布了一些详细信息和示例代码here。

您可能希望将您的应用级 InheritedWidget 设为 MaterialApp 而不是 Scaffold 小部件的父级。

我认为这与您如何设置 MaterialWidget 有更多关系,但我无法从您提供的代码 sn-ps 中完全看出。

如果您可以添加更多上下文,我会看看我是否可以提供更多。

【讨论】:

谢谢阿什顿!伟大的思想和例子。最后,根据上面与 Darky 的讨论,我相信这将成为尝试跨路由使用继承的小部件的问题。干杯! @KBDrums 太棒了!也许链接的例子会给你一些关于在路由/材质应用程序之上构造 InheritedWidget 的想法,这样你就可以保持不变 @AshtonThomas 您在答案中提供的链接已失效。请在您的回答中提供实际内容。

以上是关于带有 Scaffold 的 InheritedWidget 似乎无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章

Flutter Row 没有占用完整的 Scaffold 高度

带有浮动顶栏的脚手架(Jetpack Compose)

Scaffold Rails 3 视图中的外键下拉列表

[Scaffold]Flutter中的脚手架

Snackbar 和异常:scaffold.of()

如何在颤振中使用嵌套的 WillPopScope