在下面的代码中,当点击按钮时,为啥不能调用[print("BBB's build function.")]?

Posted

技术标签:

【中文标题】在下面的代码中,当点击按钮时,为啥不能调用[print("BBB\'s build function.")]?【英文标题】:In the following code, when the button is clicked, why can't [print("BBB's build function.")] be called?在下面的代码中,当点击按钮时,为什么不能调用[print("BBB's build function.")]? 【发布时间】:2020-11-23 05:06:11 【问题描述】:

在下面的代码中,当按钮被点击时,为什么不能调用[print("BBB's build function.")]? 下面的代码中,当按钮被点击时,为什么不能调用[print("BBB的构建函数")]?

  import 'package:flutter/material.dart';

class MyTest extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: AAA(
            child: BBB(),
          ),
        ),
      ),
    );
  


class AAA extends StatefulWidget 
  AAA(Key key, @required this.child) : super(key: key);
  final Widget child;

  @override
  _AAAState createState() => _AAAState();


class _AAAState extends State<AAA> 
  @override
  Widget build(BuildContext context) 
    print("AAA's build function.");
    return FlatButton(
      onPressed: () 
        setState(() );
      ,
      child: widget.child,
    );
  


class BBB extends StatefulWidget 
  @override
  _BBBState createState() => _BBBState();


class _BBBState extends State<BBB> 
  @override
  Widget build(BuildContext context) 
    print("BBB's build function.");
    return Text("text");
  

【问题讨论】:

【参考方案1】:

我相信这是因为 Flutter 优化了小部件的重建。换句话说,在你按下 FlatButton 并调用 setState 后,Flutter 会重建 AAA,因为你明确要求它(通过调用 setState)。

在那之后,Flutter 还将寻求重建所有 AAA 的孩子。但在此之前,Flutter 足够聪明地检查是否值得重建 AAA 的 children。 Flutter 会将现有的 BBB 小部件与重新构建的新 BBB 小部件进行比较。如果它们相同,flutter 将中止 BBB 的重建以节省资源/优化重建。

在您的情况下,它们是相同的。现有 BBB 和新 BBB 的 return 值没有区别。总是Text("text")。该函数不返回您的 print(bbb...) 行。它位于 return 语句之前。

Check out this answer from Remi (creator of Provider package) on more info about the topic.

【讨论】:

【参考方案2】:

因为每次返回同一个孩子。 (已经建成)

如果您想在每次需要使用 LayoutBuilder 时调用 Build 函数。

用你的代码和我的更改检查我的 codepen

Codepen

    import 'package:flutter/material.dart';

void main() 
  runApp(
    MaterialApp(
      home: MyTest(),
    ),
  );


class MyTest extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: AAA(
            child: (context) => BBB(),
          ),
        ),
      ),
    );
  


class AAA extends StatefulWidget 
  AAA(Key key, @required this.child) : super(key: key);
  final Widget Function(BuildContext) child;

  @override
  _AAAState createState() => _AAAState();


class _AAAState extends State<AAA> 
  @override
  Widget build(BuildContext context) 
    print("AAA's build function.");
    return FlatButton(
        onPressed: () 
          setState(() );
        ,
        child: LayoutBuilder(builder: (context, constrains) => widget.child(context)));
  


class BBB extends StatefulWidget 
  @override
  _BBBState createState() => _BBBState();


class _BBBState extends State<BBB> 
  static int p = 0;
  @override
  Widget build(BuildContext context) 
    p++;
    return Text("text$p");
  

【讨论】:

【参考方案3】:
child: AAA(
 child: BBB(),
 ),

AAA() 类在构造函数中采用widget,在您的代码中,您将传递BBB() 小部件。当你第一次运行这段代码时,你会得到:

AAA's build function.
BBB's build function.

因为这两个类都在构建中。现在FlatButtonAAA 类中,当你单击它时,setState() 被调用,setState() 将调用AAA 类的build() 方法,因此你在单击时进入控制台:

AAA's build function.

【讨论】:

以上是关于在下面的代码中,当点击按钮时,为啥不能调用[print("BBB's build function.")]?的主要内容,如果未能解决你的问题,请参考以下文章

隐藏其他类的按钮

用showwindow函数显示窗体,不能显示按钮,且无法关闭,为啥

为啥我不能更改表格页脚的文本颜色?

角度路由器导航问题

为啥按钮在点击时改变位置?

为啥在这个应用程序中按钮点击会发生两次?