我只需要了解在调用setState()时,抖动的有状态小部件如何构建其有状态的子级。请查看下面的代码。
class MyStatefulWidget extends StatefulWidget {
MyStatefulWidget({Key key}) : super(key: key);
@override
_MyStatefulWidgetState createState() => _MyStatefulWidgetState();
}
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
Widget build(BuildContext context) {
print("Parent build method invoked");
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
StatefulChild(), // Keeping this line gives the output 1
statefulChild, // Keeping this line gives the output 2
RaisedButton(
child: Text('Click me'),
onPressed: () {
setState(() {});
},
)
],
),
),
);
}
StatefulChild statefulChild = StatefulChild();
}
class StatefulChild extends StatefulWidget {
StatefulChildState createState() => StatefulChildState();
}
class StatefulChildState extends State<StatefulChild> {
@override
Widget build(BuildContext context) {
print("Child00 build method invoked");
return Container();
}
}
按下RaisedButton时,
输出1 //仅保留StatefulChild()
,
I/flutter ( 2903): Parent build method invoked
I/flutter ( 2903): Child00 build method invoked
输出2 //仅保留statefulChild
,
I/flutter ( 2903): Parent build method invoked
这里有什么区别?引擎盖下会发生什么?非常感谢详细的解释。
答案 0 :(得分:1)
重建窗口小部件树时,Flutter使用==
比较build
方法返回的先前和新窗口小部件。
在这种情况下有两种情况:
==
是false
。在这种情况下,Flutter将比较runtimeType
和key
以确定是否应保留前一个小部件的状态。然后Flutter在该小部件上调用build
==
是true
。在这种情况下,Flutter会中止构建小部件树(也不会调用build
)。
由于小部件的不变性,这是一种优化的可能。
由于小部件是不可变的,因此如果==
没有更改,则意味着没有任何要更新的内容。因此Flutter可以安全地对其进行优化。
答案 1 :(得分:0)
使用setState(())
时只会调用build()
。现在,在此方法中,您再次调用StatefulChild()
(第一行),它进一步实例化了该类,因此该类的build()
方法得以执行。
但是当您使用statefulChild
时,它并没有创建新实例,因为
StatefulChild statefulChild = StatefulChild();
在build()
方法之外使用。所以它只被调用过一次。