在下面的代码中,当点击按钮时,为啥不能调用[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.
因为这两个类都在构建中。现在FlatButton
在AAA
类中,当你单击它时,setState()
被调用,setState()
将调用AAA
类的build()
方法,因此你在单击时进入控制台:
AAA's build function.
【讨论】:
以上是关于在下面的代码中,当点击按钮时,为啥不能调用[print("BBB's build function.")]?的主要内容,如果未能解决你的问题,请参考以下文章