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(); }, ), ); } }
关键注意事项
- 控制器持有:通过类级变量保存
GoogleMapController实例,确保在任何需要的时刻能调用setMapStyle。 - 生命周期监听:借助
WidgetsBindingObserver监听应用从后台返回的resumed状态,触发样式更新。 - 主题变化监听:重写
didChangeDependencies,在系统主题切换时自动检测并更新地图样式。 - 样式加载:提前从asset加载样式文件,避免实时读取导致的延迟;确保JSON格式正确,可通过在线工具验证样式语法。
内容的提问来源于stack exchange,提问作者sub
相关产品推荐
相关产品推荐

