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

ListView.builder构建的ModalBottomSheet空白问题(关联Google Places API)

问题原因及修复方案

核心原因分析

弹窗空白最可能的原因是_placeModel!.length为0,导致ListView.builder没有生成任何列表项。另外,点击Marker通常对应单个地点,用ListView.builder包裹单个地点的信息不符合逻辑,反而容易引发数据匹配问题。

具体修复步骤

1. 先确认数据是否正确加载

在调用showModalBottomSheet前,打印_placeModel的长度和内容,验证数据是否从Google Places API成功获取并赋值:

_onMarkerTapped() {
  print("Place model length: ${_placeModel!.length}");
  print("Place model data: ${_placeModel}");
  // 后续弹窗代码
}

如果打印结果显示长度为0,需要检查API请求逻辑:

  • 确认API密钥、请求参数是否正确
  • 检查数据解析代码,确保返回的JSON正确映射到_placeModel
  • 确认请求完成后才调用_onMarkerTapped,避免在数据未加载时触发弹窗

2. 调整弹窗内容结构(针对单个地点场景)

因为点击Marker对应单个地点,无需使用ListView.builder,直接返回包含信息的Column即可,同时添加高度约束避免弹窗高度异常:

_onMarkerTapped() {
  // 先判断_placeModel是否有数据,避免空指针
  if (_placeModel == null || _placeModel!.isEmpty) return;

  showModalBottomSheet<void>(
    enableDrag: true,
    elevation: 10,
    shape: const RoundedRectangleBorder(
      borderRadius: BorderRadius.vertical(top: Radius.circular(50.0))
    ),
    context: context,
    builder: (BuildContext context) {
      // 取第一个地点(如果是单个地点的场景)
      final place = _placeModel![0];
      return SizedBox(
        // 设置弹窗最大高度,避免内容过长溢出
        height: MediaQuery.of(context).size.height * 0.4,
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            ListTile(
              leading: const Icon(Icons.web),
              title: const Text('Website'),
              onTap: () => Navigator.pop(context),
            ),
            ListTile(
              leading: const Icon(Icons.home),
              title: Text('Address: ${place.address}'),
              onTap: () => Navigator.pop(context),
            ),
            ListTile(
              leading: const Icon(Icons.schedule),
              title: const Text('Hours of Operation'),
              onTap: () => Navigator.pop(context),
            ),
            ListTile(
              leading: const Icon(Icons.share),
              title: const Text('Share'),
              onTap: () => Navigator.pop(context),
            ),
          ],
        ),
      );
    }
  );
}

3. 若确实是多地点场景的优化

如果_placeModel是多个地点的列表,需要确保长度大于0,同时调整每个列表项的结构,避免重复添加相同的ListTile:

_onMarkerTapped() {
  if (_placeModel == null || _placeModel!.isEmpty) return;

  showModalBottomSheet<void>(
    enableDrag: true,
    elevation: 10,
    shape: const RoundedRectangleBorder(
      borderRadius: BorderRadius.vertical(top: Radius.circular(50.0))
    ),
    context: context,
    builder: (BuildContext context) {
      return SizedBox(
        height: MediaQuery.of(context).size.height * 0.6,
        child: ListView.builder(
          itemCount: _placeModel!.length,
          itemBuilder: (BuildContext context, int index) {
            final place = _placeModel![index];
            // 每个地点对应一组信息,添加分割线区分
            return Column(
              children: [
                ListTile(
                  leading: const Icon(Icons.place),
                  title: Text('地点 ${index+1}'),
                ),
                ListTile(
                  leading: const Icon(Icons.home),
                  title: Text('Address: ${place.address}'),
                  onTap: () => Navigator.pop(context),
                ),
                const Divider(height: 1),
              ],
            );
          },
        ),
      );
    }
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 16:25:35