You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中StreamBuilder销毁重建后停止重绘问题排查

问题:StreamBuilder接收数据但不触发Widget重绘

项目结构

我有一个使用StreamBuilder监听并渲染列表的Widget(已省略无关细节):

class CloseUsersFromStream extends StatelessWidget {
  final Stream<List<User>> _stream;
  const CloseUsersFromStream(this._stream);

  @override
  Widget build(BuildContext context) {
    return StreamBuilder<List<User>>(
      stream: _stream,
      builder: _buildWidgetFromSnapshot,
    );
  }

  Widget _buildWidgetFromSnapshot(_, AsyncSnapshot<List<User>> snapshot) {
    if (_snapshotHasLoaded(snapshot)) {
      return UsersButtonsList(snapshot.data!);
    } else {
      return const Center(child: CircularProgressIndicator());
    }
  }

  bool _snapshotHasLoaded(AsyncSnapshot<List<User>> snapshot) {
    return snapshot.hasData;
  }
}

其父Widget代码如下:

class CloseUsersScreen extends StatefulWidget {
  final ICloseUsersService _closeUsersService;

  const CloseUsersScreen(this._closeUsersService);

  @override
  State<CloseUsersScreen> createState() => _CloseUsersScreenState();
}

class _CloseUsersScreenState extends State<CloseUsersScreen> {
  late final Stream<List<User>> _closeUsersStream;

  @override
  void initState() {
    _initializeStream(context);
    super.initState();
  }

  @override
  void dispose(){
    _closeStream();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Column(
        children: [
          //...
          CloseUsersFromStream(_closeUsersStream),
        ],
      ),
    );
  }

  void _initializeStream(BuildContext context) {
    _closeUsersStream = widget._closeUsersService.openCloseUsersSubscription(context);
  }

  void _closeStream(){
    widget._closeUsersService.closeCloseUsersSubscription();
  }
}

问题描述

有时,StreamBuilder在流产生新事件时不会重建Widget。调试确认流运行正常,StreamBuilder也能正确接收数据(调试器会停在return UsersButtonsList(snapshot.data!);行,且snapshot.data为预期值),但Widget并未按预期重绘。目前尚未明确问题触发规律,推测可能与特定条件下销毁StreamBuilder有关(无报错信息)。此外,项目中另一个StreamBuilder也出现同样问题。

已尝试的解决方案

  • 自定义StreamBuilder:自行实现CustomStreamBuilder,问题依旧,调试显示代码执行但Widget不重绘。
  • 使用ValueListenableBuilder:配合MyStreamNotifier实现,调试器走到notifyListeners()但未触发builder函数。
  • 添加UniqueKey:给StreamBuilder添加UniqueKey,问题未解决。
  • 延迟销毁流:延迟1秒关闭流,问题依旧。
  • 强制更新:将StreamBuilder改为StatefulWidget并在initState中调用setState,无效。
  • 延迟初始化StreamBuilder:直到流初始化完成再渲染StreamBuilder,无效。
  • 替换子Widget:将子Widget替换为简单Text,问题仍存在。

复现步骤

  1. 后端:克隆仓库,执行docker compose up启动服务。
  2. 前端:克隆仓库,修改lib/config/config.dart中的serverURL为本地IP。
  3. 操作流程:注册账号→进入第二屏点击“Cerrar sesión”→登录同一账号→再次进入第二屏→返回主屏幕,问题大概率出现(可能需重复1-2次)。

内容的提问来源于stack exchange,提问作者Lucas Tomic

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 20:09:50