有人能给我解释一下构建器类在Flutter中的作用吗?

wpcxdonn  于 2022-12-24  发布在  Flutter
关注(0)|答案(3)|浏览(129)

该文档非常混乱和模糊。以下是它的声明:

    • 生成器类**

一个柏拉图式的小部件,它调用闭包来获取其子小部件。
以下是我的问题:
1.他们说的"柏拉图式"是什么意思?
1.他们所说的"结束"是什么意思?
1.这门课的目的到底是什么?

ar7v8xwq

ar7v8xwq1#

在互联网上进行了长时间的广泛研究之后,我收集了一些小片段,并将它们组合起来,对Builder类的功能进行了连贯而清晰的解释。

    • 术语:**

根据官方Flutter文件,* 生成器类 * 定义为:
一个柏拉图式的小部件,它调用闭包来获取其子小部件。

  • Platonic * 的意思是这类最简单的事情,术语 * 闭包 * 只是 * lambda * 函数的另一个名称。
    • 目的:**

这将是一个冗长的解释,但请容忍我:
在Flutter框架中,每个小部件都有一个接受BuildContext*参数的build方法:
小部件构建(BuildContext上下文){...}
我们必须记住,***context
对象是由框架自动传递给小部件的build函数的,因为框架会自动处理这件事,所以没有理由让任何小部件拥有需要接受context参数的构造函数或函数(除了build之外)。
因此,如果你试图将一个特定的
context对象传递给一个子对象,你将无法做到。你不能调用build()并手动传递你自己的 * context * 对象。我的意思是,你可以,但你将调用build函数两次:
1.你的人工呼叫。
1.框架的自动调用。
所以,我们如何传递一个特定的
context对象?这就是Builder类的作用。2Builder类的目的仅仅是构建和返回子部件。3这与其他部件有何不同?4啊哈! 5Builder类允许你传递一个特定的context对象给它的子部件。6Builder类基本上是您自己设置的构建函数。
为什么我需要传递一个特定的
context**对象?让我们看一个例子:
假设我们想要将一个新的 * SnackBar * 小部件添加到其正在返回的新的 * Scaffold * 父小部件中:

@override
  Widget build(BuildContext context) {
    return new Scaffold(
        appBar: new AppBar(
          title: new Text(widget.title),
        ),
        body: new Container(),
        /// Scaffold doesn't exist in this context here
        /// because the context thats passed into 'build'
        /// refers to the Widget 'above' this one in the tree,
        /// and the Scaffold doesn't exist above this exact build method
        ///
        /// This will throw an error:
        /// 'Scaffold.of() called with a context that does not contain a Scaffold.'
        floatingActionButton: new FloatingActionButton(onPressed: () {
          Scaffold.of(context).showSnackBar(
                new SnackBar(
                  content: new Text('SnackBar'),
                ),
              );
        }));
  }

上面的代码不起作用。* Scaffold. of(context)* 函数找不到 * Scaffold *,原因是:
1.尚未创建 * Scaffold * 小工具。
1.传递给构建函数的 * context * 对象引用父小部件,它不是 * Scaffold * 小部件。
那么,我们如何赋予SnackBar小部件访问父小部件 * Scaffold * 的权限呢?我们使用一个Builder类来传递 * Scaffold * 小部件的上下文:

@override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text(widget.title),
      ),
      body: new Container(),
      /// Builders let you pass context
      /// from your *current* build method
      /// Directly to children returned in this build method
      ///
      /// The 'builder' property accepts a callback
      /// which can be treated exactly as a 'build' method on any
      /// widget
      floatingActionButton: new Builder(builder: (BuildContext context) {
        return new FloatingActionButton(onPressed: () {
          Scaffold.of(context).showSnackBar(
                new SnackBar(
                  backgroundColor: Colors.blue,
                  content: new Text('SnackBar'),
                ),
              );
        });
      }),
    );
  }

记住,Builder类构造函数:
生成器({Key键,@必需的微件生成器生成器})
通过将构件的构建委托给通过其构造函数传递的回调函数来创建构件。
因此,在代码中:

new Builder(builder: (BuildContext context){ ... });

我们提供了一种封闭物,其:
1.包含***BuildContext上下文***参数
1.基于传递的 * 上下文 * 构建并返回子小部件。
基本上,您提供了自己的构建函数。这个闭包中的 * BuildContext context * 参数是Scaffold的上下文!
基本上就是这样。Flutter文档根本没有对此提供彻底的解释。我觉得破译古代象形文字会比解码Flutter文档更容易。

    • 摘要**:对于那些仍然难以理解这个概念的人,让我以更简洁的形式来解释一下。Builder函数只允许您获取和使用Builder小部件所在小部件的 * context * 对象。在上面的示例中,它是**new Scaffold()**小部件。请记住,唯一可用的 * context * 对象是父小部件的对象(在脚手架上面)因为当前的小部件(脚手架)还没有创建。我希望这能帮助那些还在挠头的人。
svujldwt

svujldwt2#

它基本上将构建小部件的函数转换为小部件。
当你需要传递一个小部件,但是只有一个返回小部件的函数时,你可以使用Builder小部件。

bool bar;

Widget createFooOrBarWidget() {
  if(bar) {
    return BarWidget();
  } 
  return FooWidget();
}

Widget build(BuildContext context) =>
  Container(child: Builder((context) => createFooOrBarWidget()));

你也可以用

Widget build(BuildContext context) =>
  Container(child: createFooOrBarWidget());

但前者会延迟Foo或Bar小部件的创建,直到实际调用build

xlpyo6sf

xlpyo6sf3#

    • 简单定义**

这个生成器小部件,就像它的名字所暗示的那样;用于创建具有"新上下文"的子窗口小部件。

    • 技术定义**

此生成器具有builder属性,此属性接受WidgetBuilder类型定义(WidgetBuilder类型定义是创建(返回)具有新上下文的小部件的函数的签名)
如果您想了解WidgetBuilder类型定义,请使用此链接https://api.flutter.dev/flutter/widgets/WidgetBuilder.html
用法:

    • 1**.当脚手架小部件和方法脚手架在同一个构建方法中时。

[当时scaffold. of方法无法找到最接近的Scaffold小部件,因为两者都在相同的上下文中,通过在构建方法中创建新的上下文可以解决这个问题,这就是为什么我们使用Builder小部件来创建具有New BuildContext的小部件。]
下面的代码显示了构建器小部件的实际用法,当您希望在同一个构建方法中使用Scaffold. ofScaffold小部件时

  • *(请仔细阅读这些 * 评论 -它将帮助您了解 * 背景
Widget build(BuildContext context) {                       // context - 1
  return Scaffold(
    appBar: AppBar(
      title: Text('Demo')
    ),
    body: Builder(
      // Create an inner BuildContext so that the onPressed methods
      // can refer to the Scaffold with Scaffold.of().
      builder: (BuildContext context) {                    // context - 2
        return Center(
          child: RaisedButton(
            child: Text('SHOW A SNACKBAR'),
            onPressed: () {
              Scaffold.of(context).showSnackBar(SnackBar(  // here context is (context- 2)
                content: Text('Have a snack!'),
              ));
            },
          ),
        );
      },
    ),
  );
}
    • 2**.当方法和Theme小工具的主题在同一个构建方法中时。

[here目的同上1]
下面的代码显示了构建器小部件的实际用法,当您希望在同一个构建方法中使用Theme. ofTheme小部件时

@override
Widget build(BuildContext context) {
  return MaterialApp(
    theme: ThemeData.light(),
    body: Builder(
      // Create an inner BuildContext so that we can refer to
      // the Theme with Theme.of().
      builder: (BuildContext context) {
        return Center(
          child: Text(
            'Example',
            style: Theme.of(context).textTheme.title,
          ),
        );
      },
    ),
  );
}
    • 加分**

buider属性(WidgetBuilder typedef),我们可以在许多示例中看到
下面的代码部分显示了"MaterialPageRoute如何使用builder属性获取该路径的小部件

Navigator.push(context, MaterialPageRoute<void>(
  builder: (BuildContext context) {                 //here
    return Scaffold(
      appBar: AppBar(title: Text('My Page')),
      body: Center(
        child: FlatButton(
          child: Text('POP'),
          onPressed: () {
            Navigator.pop(context);
          },
        ),
      ),
    );
  },
));

相关问题