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

异步函数返回List<LatLng>,接收函数却识别为Future<List<LatLng>>

问题解决方法

核心问题

你在_createMarker函数里调用getLocations(context)时没有使用await,而且这个函数是同步函数(无async修饰),无法直接等待异步结果,所以拿到的还是Future<List<LatLng>>类型,而非实际的List<LatLng>。另外代码里的stores变量也是异步获取的,同样存在这个问题。

解决方案

把组件改成StatefulWidget,用FutureBuilder处理异步数据加载,具体修改如下:

class MapPage extends StatefulWidget {
  const MapPage({super.key});

  @override
  State<MapPage> createState() => _MapPageState();
}

class _MapPageState extends State<MapPage> {
  late GoogleMapController mapController;
  final LatLng _center = const LatLng(51.49759646223456, -0.22884194229223435);

  void _onMapCreated(GoogleMapController controller) {
    mapController = controller;
  }

  // 合并两个异步请求,同时获取位置和店铺名称
  Future<Map<String, dynamic>> _fetchData() async {
    final locations = await buildLocations(context);
    final stores = await buildStores(context);
    return {'locations': locations, 'stores': stores};
  }

  Set<Marker> _createMarker(List<LatLng> locations, List<String> stores) {
    final markers = <Marker>{
      Marker(
          markerId: const MarkerId("marker_1"),
          position: _center,
          infoWindow: const InfoWindow(
            title: "",
            snippet: "",
          ),
          onTap: () => Navigator.push(
                context,
                MaterialPageRoute(builder: (context) => const ListPage2()),
              )),
      const Marker(
        markerId: MarkerId("marker_2"),
        position: LatLng(51.488348, -0.237461),
        icon: BitmapDescriptor.defaultMarker,
      ),
    };

    // 遍历生成店铺标记
    for (int i = 0; i < locations.length; i++) {
      if (i < stores.length) {
        markers.add(Marker(
          markerId: MarkerId(stores[i]),
          position: locations[i],
        ));
      }
    }

    return markers;
  }

  Future<List<LatLng>> buildLocations(BuildContext context) async {
    List<LatLng> locations = [];
    var collection = FirebaseFirestore.instance.collection('StoreDatabase');
    var querySnapshot = await collection.get();
    for (var queryDocumentSnapshot in querySnapshot.docs) {
      Map<String, dynamic> document = queryDocumentSnapshot.data();
      // 提取LatLng的经纬度字段,避免类型转换报错
      LatLng location = LatLng(document['Location'].latitude, document['Location'].longitude);
      locations.add(location);
    }
    return locations;
  }

  Future<List<String>> buildStores(BuildContext context) async {
    List<String> stores = [];
    var collection = FirebaseFirestore.instance.collection('StoreDatabase');
    var querySnapshot = await collection.get();
    for (var queryDocumentSnapshot in querySnapshot.docs) {
      Map<String, dynamic> document = queryDocumentSnapshot.data();
      String store = document['storeName'];
      stores.add(store);
    }
    return stores;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: FutureBuilder<Map<String, dynamic>>(
        future: _fetchData(),
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) {
            // 加载中显示转圈
            return const Center(child: CircularProgressIndicator());
          } else if (snapshot.hasError) {
            // 加载失败显示错误信息
            return Center(child: Text('加载失败: ${snapshot.error}'));
          } else if (!snapshot.hasData || snapshot.data!.isEmpty) {
            return const Center(child: Text('暂无数据'));
          } else {
            final locations = snapshot.data!['locations'] as List<LatLng>;
            final stores = snapshot.data!['stores'] as List<String>;
            return GoogleMap(
              onMapCreated: _onMapCreated,
              initialCameraPosition: CameraPosition(
                target: _center,
                zoom: 11.0,
              ),
              markers: _createMarker(locations, stores),
            );
          }
        },
      ),
    );
  }
}

关键改动说明

  • 将mapPage改为StatefulWidget,用于管理异步数据的加载状态。
  • 新增_fetchData函数,合并两个异步请求,减少重复的Firestore查询等待时间。
  • 修改_createMarker,让它直接接收已获取的locations和stores列表,同步生成标记集合。
  • 用FutureBuilder处理异步加载的全流程:等待、错误、无数据、成功,避免UI崩溃。
  • 修复buildLocations中的LatLng转换逻辑,确保从Firestore取出的位置数据能正确转为LatLng类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 09:35:22