如何最好地从子小部件访问嵌套小部件的 BuildContext?
Posted
技术标签:
【中文标题】如何最好地从子小部件访问嵌套小部件的 BuildContext?【英文标题】:How can I best access the BuildContext of a nested widget from a child widget? 【发布时间】:2018-12-25 11:00:29 【问题描述】:我在顶部有一个 StatefulWidget(我们称之为顶部小部件),它的构建函数如下所示:
@override
Widget build(BuildContext context)
return new MaterialApp(
color: // some color,
theme: // some theme,
home: new Scaffold(
backgroundColor: // some color,
body: new Builder(builder: (context)
_builderContext = context;
return new Column(
children: <Widget>[
new Expanded(
child: new MaterialApp(
color: // some color,
theme: // some theme,
title: 'title',
onGenerateRoute: _onRoute,
navigatorKey: _navigatorState,
navigatorObservers: observers,
),
),
... etc
现在,在 _onRoute 生成的子小部件的某处,我想调出带有showModalBottomSheet(context, ...)
的底部表格。但是,传递给 showModalBottomSheet 的上下文必须是来自上述构建方法中的 Builder 的上下文。如果我使用对孩子可用的上下文,则工作表会在我的 UI 的错误底部锚点处弹出。现在,孩子已经可以通过 GlobalKey 与顶部小部件进行通信了。但是,在顶部小部件的另一种方法中,我只能访问其一般上下文。将此上下文传递给 showModalBottomSheet 会引发空指针。
经过大量研究和反复试验,我想出的唯一解决方案是在构建方法中缓存上下文 (_builderContext = context;
),然后使用这个缓存的上下文将其传递到我的另一个顶部小部件中的 showModalBottomSheet方法:
openBottomSheet()
if (_builderContext != null)
showModalBottomSheet(
context: _builderContext,
builder: (context)
return // some bottom sheet content;
);
目前,这似乎工作得很好,但我想知道是否有更清洁的方法来做到这一点?
这个问题可以概括为我一般如何访问子小部件中的上下文。我尝试提出一个 InheritedWidget 解决方案,但无法真正理解如何以某种方式使 Builder 成为继承的小部件,然后将其用于我的问题。
非常感谢任何想法。
【问题讨论】:
你应该只有一个MaterialApp
实例
我遇到了关于模式和 InheritedWidget 的类似问题 - 解决方案是在我的应用程序的根目录中使用“InheritedWidget”(即/来自 main.dart)
【参考方案1】:
如果这个问题只是为了使用 ModalBottomSheet,我强烈建议你使用 Flushbar Plugin here 来解决 Flutter。
它非常灵活,您可以在很大程度上对其进行自定义。您不必立即处理上下文和其他内容——根据需要对其进行编辑,您也可以在任何地方使用它……即使您没有脚手架祖先。 (在使用底部模态表或脚手架时,它需要一个脚手架祖先)。
如果这个问题只是关于在父小部件的子小部件中使用上下文,我建议您简单地将其传递给任何class/widget(stateful/stateless)
作为参数。它使一切都非常易于使用。
【讨论】:
谢谢,我会研究一下 Flushbar 插件。至于另一个建议:如果我需要将上下文向下传递几个步骤,这当然会使小部件构造函数变得混乱。除此之外:上下文在某些时候不会变得“陈旧”吗?第三个问题是子widget不是直接嵌套在build方法中,而是通过onGenerateRoute生成的。所以无论如何我都会再次缓存上下文。【参考方案2】:当您已经拥有GlobalKey
时,您还需要key.currentContext
吗?不过,在调用它之前,请确保您测试它是否为 null,就像您对 _builderContext
所做的那样。
【讨论】:
以上是关于如何最好地从子小部件访问嵌套小部件的 BuildContext?的主要内容,如果未能解决你的问题,请参考以下文章