首页 文章

BuildContext 在 Flutter 中做了什么?

提问于
浏览
23

BuildContext做了什么,我们从中得到了什么信息?

https://docs.flutter.io/flutter/widgets/BuildContext-class.html只是不清楚。

BuildContext这个术语的第 9 个实例上https://flutter.io/widgets-intro/#basic-widgets有一个例子,但不清楚它是如何被使用的。这是一组更大的代码丢失了我的一部分,所以我很难理解BuildContext是什么。

有人可以用 simple/very 基本术语来解释这个吗?

2 回答

  • 30

    BuildContext就像它的名字所暗示的那样,是构建特定小部件的上下文。

    如果你以前做过一些 React,那个上下文有点类似于 React 的上下文(但使用得更顺畅);有一些奖金。

    一般来说,上下文有两种用例:

    • 与您的父母互动(主要是 get/post 数据)

    • 在屏幕上呈现后,获取屏幕大小和位置

    第二点有点罕见。另一方面,第一点几乎用于所有地方。

    例如,当您想要推送新路线时,您将执行Navigator.of(context).pushNamed('myRoute')

    注意这里的上下文。它将用于在树中获取上面最接近NavigatorState小部件的实例。然后在该实例上调用方法pushNamed


    很酷,但什么时候**我想用它?

    当您想要向下传递数据而不必手动将其分配给每个小部件时,BuildContext 非常有用。配置例如;你想要到处访问它们。但是你不想在每个构造函数上传递它。

    你可以创造一个全球或单身;但是当 confs 改变时,你的小部件不会自动重建。

    在这种情况下,您使用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)的小部件都会在配置发生变化时自动重建。

    真棒吗?

  • 8

    BuildContext类只不过是对构建的所有窗口小部件的树结构中窗口小部件的位置的引用。

    每个 Flutter 小部件都有一个@override build()方法,参数为BuildContext

    class CartItemWidget extends StatelessWidget {
    
      @override
      Widget build(BuildContext context) {.....
    

    简单解释一下 BuildContext 是:

    • BuildContext 仅属于一个窗口小部件。

    • BuildContext 对象被传递给 WidgetBuilder 函数

    BuildContext 只属于一个小部件.

    如果窗口小部件“A”具有子窗口小部件,则窗口小部件“A”的BuildContext将成为直接子窗口BuildContexts的父 BuildContext。

    读到这一点,很明显BuildContexts被链接并组成一个BuildContexts(parent-children 关系)的树

    在此输入图像描述

    如果我们现在尝试在上图中说明 BuildContext 的概念,我们获得(仍然是一个非常简化的视图),其中每种颜色代表一个 BuildContext(除了 MyApp,它是不同的):

    以下显示了与创建状态窗口小部件相关的 actions/calls 序列(简化版本)。

    窗口小部件的状态与参数无关,但每次参数更改时都会重建。在这种情况下,需要使用InheritedWidget

    InheritedWidget是一种特殊的小部件,它定义了 sub-tree 根的上下文。它可以有效地将此上下文传递给 sub-tree 中的每个小部件。 Flutter 开发人员看起来很熟悉访问模式:

    class MyInheritedWidget extends InheritedWidget {
    
    MyInheritedWidget({
          Key key,
          @required Widget child,
          this.data,
       }): super(key: key, child: child);
    
       final data;
    
       static MyInheritedWidget of(BuildContext context) {
          return context.inheritFromWidgetOfExactType(MyInheritedWidget);
       }
    
       @override
       bool updateShouldNotify(MyInheritedWidget oldWidget) => data != oldWidget.data;
    }
    

    static MyInheritedWidget of(BuildContext context)方法允许所有子窗口小部件获取最接近上下文的MyInheritedWidget“的实例

    最后,updateShouldNotify重写方法用于告诉InheritedWidget如果对数据应用修改,是否必须将通知传递给所有子窗口小部件(registered/subscribed)

    欲获得更多信息

相关问题