Flutter 中的 BuildContext 是什么?

86

2
Flutter官方YouTube频道发布了一段视频,解释了它的使用方法这里 - MendelG
1
@MendelG,这仍然没有添加太多的上下文! - Teoman shipahi
2个回答

112
BuildContext是指一个特定widget被构建的上下文。类似于React的context,但更易用且具有一些额外的优点。通常来说,有两种使用情况:
- 与父widget交互(主要是获取/发送数据) - 渲染完成后获取屏幕尺寸和位置
第二个点比较少见。而第一个点则几乎在任何地方都会用到。例如,当你想要推送一个新路由时,你会这样做:Navigator.of(context).pushNamed('myRoute')
注意上述代码中的context。它将被用来获取树中最近的NavigatorState widget实例,然后调用该实例上的pushNamed方法。
那么什么时候需要使用BuildContext呢?当你想要向下传递数据而不必手动为每个widget的配置分配数据时,BuildContext非常有用。你希望随处都能访问它们,但不想在每个构造函数中都传递数据。
你可以潜在地创建一个全局或单例;但是当配置发生变化时,你的widgets不会自动重建。在这种情况下,你可以使用InheritedWidget,例如:
class Configuration extends InheritedWidget {
  final String myConf;

  const Configuration({this.myConf, Widget child}): super(child: child);

  @override
  bool updateShouldNotify(Configuration oldWidget) {
    return myConf != oldWidget.myConf;
  }
}

然后,使用它的方法如下:

void main() {
  runApp(
    new Configuration(
      myConf: "Hello world",
      child: new MaterialApp(
        // usual stuff here
      ),
    ),
  );
}

感谢此举,现在 无论何处 在您的应用内,您都可以使用 BuildContext 访问这些配置。通过这样做

final configuration = context.inheritFromWidgetOfExactType(Configuration);

更酷的是,调用inheritFromWidgetOfExactType(Configuration)所有小部件将在配置更改时自动重建。

很棒吧?


1
谢谢。只是为了澄清,您提到它允许您与父母互动。在您的示例中,似乎BuildContext正在与包含BuildContext的小部件的子级进行交互。我看得对吗? - richalot
1
是子组件使用它们自己的上下文来请求其父组件的信息。 - Rémi Rousselet
2
你需要上下文才能访问它。但是你可以在 initState 中访问上下文。 - Rémi Rousselet
5
initState 中怎么办?每次我输入 context 都会出现红色波浪线 :) - Jus10
2
实际上,这次编辑是不必要的。原帖作者最初的句子是正确的(不是“...例如小部件的配置...”,而是“...小部件。例如配置...”)。 此外,“inheritFromWidgetOfExactType”现在已被弃用,请使用“yourContext.dependOnInheritedWidgetOfExactType<YourInheritedWidget>();”。 - starriet
显示剩余4条评论

19

BuildContext对象/上下文是什么?

在了解BuildContext之前,我们需要知道Element对象。

什么是Element对象?

(注意:作为Flutter开发者,我们从未直接使用过Element对象,但我们使用类似于Element对象的对象(称为BuildContext对象))

Element对象是当前widget的构建位置。

“构建位置”真正意味着什么?

  1. 当框架通过调用其构造函数构建小部件对象时,相应地需要为该小部件对象创建元素对象。
  1. 而此元素对象表示该小部件的构建位置。
  1. 该元素对象具有许多有用的实例方法。

谁使用Element对象及其方法?

有两个使用Element对象及其方法的方面:

  1. 框架(创建RenderObject树等)
  2. 开发人员(像我们一样)

BuildContext对象是什么?

BuildContext对象实际上是Element对象。 BuildContext接口用于防止直接操作Element对象。

因此,BuildContext对象=不建议使用的元素对象(与原始Element对象相比包含较少的实例方法)

为什么框架不建议使用Element对象并将其传递给我们?

因为Element对象具有只有框架本身才需要的实例方法。 但是,当我们自己访问这些方法时,这是不应该做的事情。 这就是框架不建议使用Element对象并将其传递给我们的原因。



好的,现在让我们谈谈主题

Flutter中BuildContext对象的作用是什么?

BuildContext对象具有多个有用的方法,可轻松执行需要在小部件树中完成的某些任务。

  1. findAncestorWidgetOfExactType()。

    返回给定类型T的最近祖先widget。

  2. findAncestorStateOfType()。

    返回最近祖先StatefulWidget的State对象。

  3. dependOnInheritedWidgetOfExactType()。

    获取给定类型T的最近小部件,该类型必须是具体InheritedWidget子类的类型,并向该小部件注册此构建上下文,以便在该小部件更改时进行更改。 [由Provider软件包使用]

上述方法大多是BuildContext对象的实例方法,如果您想查看该BuildContext对象的所有方法,请访问此链接+查看@remi Rousselot的答案。


1
非常好的答案!谢谢你!:) 为什么在第1点和第2点中要编写findAncestorWidgetOfExactType - Aleksandar
1
@Aleksandar 哦!这是一个错误,我已经纠正了。谢谢您。 - dilshan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接