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

Google Maps Flutter自定义瓦片图层渲染管控与加载状态实现咨询

解决方案:在自定义瓦片生成期间显示加载状态

可以实现,结合google_maps_flutter: ^2.10.0的TileProvider特性和Flutter状态管理,就能在客户端生成瓦片时显示加载状态,具体步骤如下:


1. 改造自定义瓦片Provider,跟踪加载状态

给你的CustomTileProvider添加加载计数的状态管理,通过ValueNotifier实时通知UI加载状态:

class CustomTileProvider extends TileProvider {
  final List<Area> areas;
  final ValueNotifier<int> loadingTileCount = ValueNotifier(0);

  CustomTileProvider(this.areas);

  @override
  Future<Tile> loadTile(int x, int y, int? zoom) async {
    // 开始加载瓦片,计数+1
    loadingTileCount.value++;
    try {
      // 替换成你客户端生成瓦片的实际逻辑
      final Uint8List tileBytes = await _generateCustomTile(x, y, zoom);
      return Tile(x, y, tileBytes);
    } finally {
      // 无论成功失败,加载完成后计数-1
      loadingTileCount.value--;
    }
  }

  // 模拟客户端生成瓦片的方法,替换成你的实际代码
  Future<Uint8List> _generateCustomTile(int x, int y, int? zoom) async {
    // 比如通过Canvas绘制瓦片内容并转成Uint8List
    // ...
    await Future.delayed(Duration(milliseconds: 200)); // 模拟生成耗时
    return Uint8List(0);
  }
}

2. 在地图页面集成加载状态UI

用Stack将地图和加载遮罩层叠,通过监听Provider的加载计数,控制遮罩的显示:

class MapScreen extends StatefulWidget {
  @override
  _MapScreenState createState() => _MapScreenState();
}

class _MapScreenState extends State<MapScreen> {
  late GoogleMapController _mapController;
  late CustomTileProvider _tileProvider;
  final String _tileID = 'custom-area-tiles';
  final ValueNotifier<bool> _isLoading = ValueNotifier(false);

  @override
  void initState() {
    super.initState();
    _tileProvider = CustomTileProvider(Areas);
    // 监听加载中的瓦片数量,数量>0时显示加载状态
    _tileProvider.loadingTileCount.addListener(_updateLoadingState);
  }

  void _updateLoadingState() {
    _isLoading.value = _tileProvider.loadingTileCount.value > 0;
  }

  @override
  void dispose() {
    _tileProvider.loadingTileCount.dispose();
    _isLoading.dispose();
    super.dispose();
  }

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

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        GoogleMap(
          onMapCreated: _onMapCreated,
          initialCameraPosition: const CameraPosition(
            target: LatLng(37.7749, -122.4194), // 示例坐标
            zoom: 10,
          ),
          tileOverlays: {
            TileOverlay(
              tileOverlayId: TileOverlayId(_tileID),
              tileProvider: _tileProvider,
              zIndex: 1,
            ),
          },
          // 可选:在地图开始移动/缩放时立即显示加载状态,提升用户感知
          onCameraMoveStarted: () => _isLoading.value = true,
        ),
        // 加载状态遮罩
        ValueListenableBuilder<bool>(
          valueListenable: _isLoading,
          builder: (context, isLoading, child) {
            if (!isLoading) return const SizedBox.shrink();
            return Container(
              color: Colors.black.withOpacity(0.5),
              child: const Center(
                child: CircularProgressIndicator(color: Colors.white),
              ),
            );
          },
        ),
      ],
    );
  }
}

关键说明

  • 状态跟踪逻辑:通过loadTile方法的开始/结束时机更新加载计数,确保所有瓦片加载完成后才隐藏加载状态。
  • UI层控制:用ValueListenableBuilder监听加载状态,避免不必要的setState,提升性能。
  • 版本兼容:google_maps_flutter: ^2.10.0支持异步loadTile,该方案完全适配此版本。
  • 异常处理:finally块确保即使瓦片生成失败,也会更新加载计数,避免状态卡住。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 06:54:53