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

如何从StreamController中获取'data'值?附Flutter代码示例

解决Flutter中StreamController数据在Marker InfoWindow中使用的问题

你的核心问题是异步流数据无法直接同步用于Marker的InfoWindow标题,而且当前代码每次onTap都订阅Stream会导致重复订阅,浪费资源还可能引发内存泄漏。下面给出两种可行的实现方式:

方式一:手动管理Stream订阅与组件状态

使用StatefulWidget维护流数据状态,在组件生命周期内仅订阅一次Stream:

// children.dart 子组件文件
class ChildrenMap extends StatefulWidget {
  const ChildrenMap({super.key});

  @override
  State<ChildrenMap> createState() => _ChildrenMapState();
}

class _ChildrenMapState extends State<ChildrenMap> {
  String? _streamData;
  StreamSubscription? _streamSubscription;

  @override
  void initState() {
    super.initState();
    // 组件初始化时订阅Stream,仅订阅一次
    _streamSubscription = ctrl.stream.listen((data) {
      // 更新状态,触发组件重建
      setState(() {
        _streamData = data;
      });
    });
  }

  @override
  void dispose() {
    // 组件销毁时取消订阅,避免内存泄漏
    _streamSubscription?.cancel();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return GoogleMap(
      onTap: (LatLng latlng) {
        // 直接使用已保存的_streamData创建Marker
        Marker(
          position: latlng,
          infoWindow: InfoWindow(
            title: _streamData ?? '默认标题', // 用空值运算符处理未收到数据的情况
          ),
          // 补充Marker的其他必要属性
        );
      },
      // ...GoogleMap的其他属性
    );
  }
}

方式二:使用StreamBuilder自动管理订阅

StreamBuilder会自动处理Stream的订阅与取消,无需手动管理生命周期:

// children.dart 子组件文件
GoogleMap(
  onTap: (LatLng latlng) {
    // 用StreamBuilder包裹Marker,自动响应Stream数据变化
    StreamBuilder(
      stream: ctrl.stream,
      initialData: '默认标题', // 设置初始标题,可选
      builder: (context, snapshot) {
        String title = '默认标题';
        if (snapshot.hasData) {
          title = snapshot.data.toString();
        }
        return Marker(
          position: latlng,
          infoWindow: InfoWindow(title: title),
          // 补充Marker的其他必要属性
        );
      },
    );
  },
  // ...GoogleMap的其他属性
);

注意事项

  • 绝对不要在onTap回调内重复调用ctrl.stream.listen(),每次调用都会创建新的订阅,可能导致多次打印重复数据,还会引发内存泄漏。
  • 如果你的全局StreamController不再使用,记得调用ctrl.close()释放资源。

内容的提问来源于stack exchange,提问作者Ae Gg

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 06:24:25