BuildContext在Flutter中做了什么?

时间:2018-03-04 20:38:07

标签: flutter

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

https://docs.flutter.io/flutter/widgets/BuildContext-class.html目前尚不清楚。

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

有人可以用简单/非常基本的术语解释这个吗?

3 个答案:

答案 0 :(得分:29)

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

如果您以前做过某些React,那么该上下文与React的上下文类似(但使用起来更顺畅);有一些奖金。

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

  • 与您的父母互动(主要获取/发布数据)
  • 在屏幕上呈现后,获取您的屏幕尺寸和位置

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

例如,当您想要推送新路线时,您将执行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)所有小部件将自动重建。

太棒了吧?

答案 1 :(得分:6)


Flutter小部件树,由02种小部件组成。

1-类小部件(父小部件/类通过无状态或有状态小部件扩展)

2-构建小部件(子小部件/小部件由build()返回

两个小部件都有其自己的上下文。


上下文

上下文实际上是什么意思????

context是一个包含value(object)的参数(变量),value = 该窗口小部件的位置(位置)。

注意:-构建小部件时,此参数的值(位置)/参数由Framework自动给出。所以不要考虑此参数如何获取值

每个小部件都有一个构建位置吗?

,每个小部件都具有构建位置,没有该位置框架就无法创建该小部件树的元素树。(请记住,它对开发人员也有用)

有02种上下文

1-类窗口小部件上下文(父窗口小部件)

2-构建小部件上下文(子小部件)

  • 类窗口小部件上下文-我们看不到该上下文,它仅由框架本身用于创建元素树。

  • 构建窗口小部件上下文-该上下文对我们来说是可见的,可以通过框架使用,也可以出于某些目的使用(例如:-用于访问祖先小部件)

-------------------------------------------- ------------------------------------------

构建小部件上下文/ BuildContext上下文

build小部件上下文是您为build()方法传递的上下文类型(如下代码)

@override
Widget build(BuildContext context) {            //BuildContext
  return Text(
    'Example',
    style: Theme.of(context).textTheme.title,
  );
}

每个人都知道变量或参数有其自己的类型。 (例如int,double,String等)

因此,此上下文参数的类型也称为“ BuildContext”

(这个特殊的名称“ BuildContext”很好地表示了该上下文的含义,因为此上下文归build方法所有,所以它的名称为“ BuildContext”)


该小部件的位置

要回答此问题,请参见下面的代码,它将向您显示该小部件的构建位置(并且此位置是上下文对象(参数)中的存储。

请参见下面的浮动代码,在其中可以看到注释 //here is the location of this child widget is build.此注释表示该子窗口小部件的构建位置。

示例代码-1

@override
Widget build(BuildContext context) {
  //here is the location of this child widget is build.
  return Text(
    'Example',
    style: Theme.of(context).textTheme.title,
  );
}

示例代码-2

@override
  Widget build(BuildContext context) {
    // here build location of that widget                     //here
    return Scaffold(
      appBar: AppBar(title: Text('Demo')),
      body: Builder(
        // here build location of that widget                 //here
        builder: (BuildContext context) {
          return FlatButton(
            child: Text('BUTTON'),
            onPressed: () {
              Scaffold.of(context).showSnackBar(SnackBar(
                content: Text('Hello.')
              ));
            }
          );
        }
      )
    );
  }

在这篇文章中,我看到了有关上下文的含义。但是在这里,我没有显示使用 BuildContext上下文的案例,但是@Remi Rousselet 的答案显示了一些用例。

希望这对您有帮助

答案 2 :(得分:5)

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

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

class CartItemWidget extends StatelessWidget {

  @override
  Widget build(BuildContext context) {.....

简单解释一下,BuildContext是:

  1. BuildContext仅属于一个小部件。
  2. BuildContext对象传递给WidgetBuilder函数

BuildContext仅属于一个小部件。

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

阅读此书后,很明显BuildContexts是链接在一起的,并且正在构成BuildContexts(父母与子女的关系)的树

enter image description here

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

以下diagram显示了与创建有状态窗口小部件有关的动作/调用的顺序(的简化版本)。

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

InheritedWidget是一种特殊的小部件,它在子树的根处定义上下文。它可以有效地将此上下文传递到该子树中的每个小部件。对于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,如果对数据进行了修改,是否必须将通知传递给所有子小部件(已注册/预订的子部件)< / p>

更多信息

  1. Build Context
  2. Widget,State,BuildContext,InheritedWidget
  3. Inheriting Widgets