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

Flutter中Google Maps随系统明暗模式切换及后台返回更新问题

解决方案:Flutter Google Maps 随明暗模式切换+后台返回更新样式

核心问题分析

onMapCreated 仅在地图首次初始化时触发一次,应用从后台返回或系统明暗模式切换时,地图实例已存在,不会再次触发该回调。因此必须通过持有地图控制器实例,主动触发样式更新。

实现步骤及代码示例

import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:flutter/services.dart';

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

  @override
  State<MapScreen> createState() => _MapScreenState();
}

class _MapScreenState extends State<MapScreen> with WidgetsBindingObserver {
  GoogleMapController? _mapController;
  String? _lightMapStyle;
  String? _darkMapStyle;
  String? _currentMapStyle;

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
    // 提前加载明暗模式对应的地图样式文件
    _loadMapStyles();
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    _mapController?.dispose();
    super.dispose();
  }

  // 监听应用生命周期,后台返回时更新样式
  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    if (state == AppLifecycleState.resumed) {
      _updateMapStyle();
    }
  }

  // 监听主题变化,系统明暗模式切换时自动更新
  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    final targetStyle = Theme.of(context).brightness == Brightness.dark 
        ? _darkMapStyle 
        : _lightMapStyle;
    if (targetStyle != _currentMapStyle) {
      _currentMapStyle = targetStyle;
      _updateMapStyle();
    }
  }

  // 从asset加载地图样式文件
  Future<void> _loadMapStyles() async {
    _lightMapStyle = await rootBundle.loadString('assets/map_style_light.json');
    _darkMapStyle = await rootBundle.loadString('assets/map_style_dark.json');
    // 初始化当前主题对应的样式
    _currentMapStyle = Theme.of(context).brightness == Brightness.dark 
        ? _darkMapStyle 
        : _lightMapStyle;
    _updateMapStyle();
  }

  // 统一更新地图样式的方法
  void _updateMapStyle() {
    if (_mapController != null && _currentMapStyle != null) {
      // 可加入try-catch捕获样式格式错误
      try {
        _mapController!.setMapStyle(_currentMapStyle);
      } catch (e) {
        debugPrint('地图样式设置失败: $e');
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: GoogleMap(
        initialCameraPosition: const CameraPosition(
          target: LatLng(31.2304, 121.4737),
          zoom: 12,
        ),
        onMapCreated: (controller) {
          _mapController = controller;
          // 地图首次创建时设置初始样式
          _updateMapStyle();
        },
      ),
    );
  }
}

关键注意事项

  1. 控制器持有:通过类级变量保存GoogleMapController实例,确保在任何需要的时刻能调用setMapStyle。
  2. 生命周期监听:借助WidgetsBindingObserver监听应用从后台返回的resumed状态,触发样式更新。
  3. 主题变化监听:重写didChangeDependencies,在系统主题切换时自动检测并更新地图样式。
  4. 样式加载:提前从asset加载样式文件,避免实时读取导致的延迟;确保JSON格式正确,可通过在线工具验证样式语法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 09:13:10