Flutter BlocBuilder 不调用新状态

标签 flutter dart bloc

我的 Bloc 正在产生新的国家,例如像这样:

yield Loaded();
yield Loaded();

我的 BlocListener 会检索这两个内容,即使它们是相同的。

另一方面,我的 BlocBuilder 则不然。它只会检索第一个(或最后一个?)。

我没有使用 equatable,我不明白为什么 BlocBuilder 不会两次被触发。

就我而言,我只是想再次更新 UI,而不实际更改状态。

最佳答案

构建小部件是一项昂贵的任务,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不会立即导致重建。 setState 将立即调用传递给它的闭包,然后将您的小部件标记为脏(以便在下一帧中重建)。这就是为什么多次调用 setState 只会触发一次小部件的 build 方法。现在,如果您将该代码中的最后一个 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),
  );
}

正如您所看到的,我们在示例中看到的相同行为也适用于此处,如果您在短时间内重复生成多个状态,它将使用最新状态构建一次。

关于Flutter BlocBuilder 不调用新状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63909409/

相关文章:

Flutter ListView.Builder() 在可滚动列中与其他小部件

flutter - 如何在 flutter 中听焦点变化?

flutter - 状态变化时的 Bloc 导航

android - Flutter 集成测试 - 如何在单个命令或单个文件中运行多个 Flutter 集成测试的测试用例

Flutter_bloc : ^8. 0.0 状态在使用不同 Prop 发出相同状态时不会重建

Flutter BLoC - Bloc vs Cubit 事件驱动状态管理优势

flutter - 如何获取用户的 Facebook 用户名或 ID?

flutter - 我需要在 Flutter 中重现一个 Floating Action Button,它可以转换成一个横跨整个屏幕的新表面

flutter - Flutter中有没有办法获取图片的元数据?

intellij-idea - 在intellij dart中使用Sass变压器