【问题标题】:When the build function really needed in flutter app?Flutter 应用程序中何时真正需要构建功能?
【发布时间】:2020-05-16 07:46:53
【问题描述】:

我对 Flutter 应用程序完全陌生,但在 android/kotlin 中有很强的概念。我试图了解颤振应用程序的基本结构。我读到每个小部件都需要一个 build 函数来覆盖以绘制对我来说很好的孩子,因为在 android/kotlin 中有 onCreate(); 或类似的其他小部件。然后我在官方文档页面看到了这段代码。

void main() {
  runApp(
    Center(
      child: Text(
        'Hello, world!',
        textDirection: TextDirection.ltr,
      ),
    ),
  );
}

没有build() 函数也可以正常工作,那么构建函数的真正目的是什么?当我们需要它的时候?什么可以没有它,什么不能?

【问题讨论】:

  • 确实调用了所有相关小部件的build 方法。定义自定义小部件类时,必须实现 build 方法。你一般不会自己直接调用。

标签: flutter flutter-widget


【解决方案1】:

虽然您可以将所有内容直接传递给runApp,但它有一个很大的缺点:

您的应用将是静态的。如果没有build 函数(或builderFutureBuilder 类似),那么您的应用将无法拥有动态内容。

这对可重用性也很不利。您可能希望将此小部件树的某些部分提取到自定义小部件中,以便在不同位置重用它们 - 这意味着该自定义小部件的 build 方法。

【讨论】:

  • 有道理,你能解释一下your app would be static吗?怎么样?
  • 因为没有办法用不同的东西重建你的应用程序的一部分。在某些时候你需要一个函数。
【解决方案2】:

Flutter 的功能与许多其他平台截然不同,build() 的名称只会增加混乱。 :-)) 为了理解它,试着暂时忘记你以前使用其他平台的经验。

Build() 真的更像 display()

Flutter 使用build() 系统显示当前帧。如果应用有快速变化的内容,例如动画或游戏,build() 每秒会被调用 60 次或更多次,即每一帧。是的,这就是意图:否不管它的名字是什么,将其视为displayCurrentFrame() 的函数,而不是名称可能暗示的内容,构建一个小部件,然后在应用程序的剩余生命周期中使用它。

系统经过完美优化,可以知道何时必须调用build()。对于不经常更改的内容,它不会每秒调用 60 次,它足够聪明,不会那样做。但是每次真正需要它时,它都会被调用(对于非常复杂的情况,你还有一些机制可以帮助 Flutter 决定何时调用以及调用什么,以确保只有真正改变的部分才会被重绘,从而可以避免在真正需要快速变化内容的应用(主要是游戏)中出现抖动)。

build() 的任务是获取您当前拥有的任何数据(称为小部件的状态)并仅使用该数据构建小部件(或小部件),仅用于那个单一的显示框架。下一次,可能使用不同的数据,您将一次又一次地构建它。

因此,Flutter 应用程序的工作方式与许多其他平台不同。您不必编写等待用户交互的代码,然后,例如,调用显示函数来直接显示新选择、新文本条目、新图像等任何内容。你所有的小部件的功能都是这样的:只要有变化,用户就会做一些事情,你通过互联网拨打的电话会得到响应,计时器已经过去,所以基本上,任何事情都会发生,你的小部件将您刚刚收到的任何新数据存储到自己的状态中,并告诉 Flutter “嘿,有变化,请给我打电话,以便我可以绘制自己的当前版本。”而且Flutter会调用它的build(),你的widget会根据这个当前的新数据显示自己。一次又一次,只要您的应用程序还活着并且正在运行。

起初,所有这些似乎都是对资源的浪费。为什么要在可能的每一帧上重建所有内容,而不是构建一个小部件,让它保持活力并在应用程序运行时使用它?唯一现实的答案是:别担心。该系统在构思时明确考虑了这种结构,它被编译成优化的代码,运行良好,快速且响应迅速。这些小部件足够轻巧,因此这并不意味着现实生活中最轻微的问题(而且,正如已经提到的,在非常复杂的程序中,它开始很重要,你可以对它应该如何工作发表意见,但你没有'也不必担心这一点,直到你达到真正重要的那个阶段)。只要习惯它并接受这就是 Flutter 的工作方式。 :-)

其他含义

所有这些还有其他含义。你不应该在build() 中做任何你在每个显示周期都不舒服的事情:既因为它不应该花费太多时间,也因为它会被一遍又一遍地调用。尤其不是任何冗长的操作。您可以启动一个异步操作(实际上,您可能在处理某些用户输入时经常这样做),但那是异步的,它会自行完成它的工作并稍后返回。当它返回时,如上所述,您将新数据存储在状态中,并在下次使用 build() 中。但是你永远不会在那里等待任何事情,或者做任何真正复杂的编程逻辑并在那里执行任务。这只不过是一个display(),真的。

【讨论】:

    猜你喜欢
    • 2021-07-18
    • 2020-10-14
    • 2010-10-22
    • 1970-01-01
    • 2010-12-12
    • 2021-02-05
    • 2020-08-21
    • 2020-03-30
    • 1970-01-01
    相关资源
    最近更新 更多