我的集团正在产生新的状态,例如像这样:
yield Loaded();
yield Loaded();
即使它们相同,我的BlocListener也会检索这两者。
我的BlocBuilder却没有。它将仅检索第一个(或最后一个?)。
我没有使用equatable,我也不明白为什么BlocBuilder不会两次都被触发。
就我而言,我只是想再次更新UI,而无需实际更改状态。
答案 0 :(得分:1)
构建窗口小部件是一项昂贵的任务,Flutter试图尽可能地减少此成本。其中之一是在状态更改时防止重复构建。这是一个示例:
class TestPage extends StatefulWidget {
@override
_TestPageState createState() => _TestPageState();
}
class _TestPageState extends State<TestPage> {
int a = 0;
@override
Widget build(BuildContext context) {
print(a);
return Scaffold(
floatingActionButton: FloatingActionButton(onPressed: () {
setState(() => a = 1);
setState(() => a = 1);
}),
);
}
}
此示例在第一个版本中打印0。单击该按钮后,您应该可以看到2张打印件,其值为1,但是在控制台中您只会收到一条消息。为什么?因为setState
是async
函数,并且在反复调用它们或在很小的时间内调用它们时,Flutter会将它们一起批处理,并且只会生成一次火灾。现在,如果将代码中的最后一个setState
更改为setState(() => a = 2)
,则在单击按钮后,控制台中将显示2。如果反转它们(首先将a设置为2,然后设置为1),则控制台中将得到1。现在考虑到这一点,让我们看看BlocBuilder
是如何工作的?
BlocBuilder
是StatefulWidget
,并使用BlocListener
更新其状态并根据需要重建小部件。这是build
方法:
@override
Widget build(BuildContext context) {
return BlocListener<C, S>(
cubit: _cubit,
listenWhen: widget.buildWhen,
listener: (context, state) => setState(() => _state = state),
child: widget.build(context, _state),
);
}
正如您所看到的,我们在示例中看到的相同逻辑也适用于此,并且如果您在短时间内重复产生多个状态,它将使用最新状态构建一次。