Skip to content

Software Development at Program Tom LTD

Place for coding, programming, development and software in general.

Menu
  • Blog
  • PDF Booklets
  • Dev Utils & Content
  • Java Spring Boot Or Web Apps
  • English
    • български
    • English
    • Español
    • Português
    • हिन्दी
    • Русский
    • Deutsch
    • Français
    • Italiano
    • العربية
  • About Us
Menu
How to set Google Map Theme in a Flutter App

How to set Google Map Theme in a Flutter App

Posted on November 23, 2025 by Toma Velev

Customizing the theme of Google Maps in a Flutter app allows you to match the map’s appearance to your app’s design, such as light/dark modes or branded styles. This is achieved using the google_maps_flutter package, which supports built-in map types and custom JSON-based styles. Below is a step-by-step guide covering setup, basic theming, custom styles, and dynamic theme switching.

Prerequisites

  • A Flutter project set up (run flutter create my_app if starting fresh).
  • A Google Maps API key from the Google Cloud Console. Enable the Maps SDK for Android/iOS.
  • Add the key to android/app/src/main/AndroidManifest.xml (inside <application>):
    xml <meta-data android:name="com.google.android.geo.API_KEY" android:value="YOUR_API_KEY"/>
  • Add it to ios/Runner/Info.plist (as a string key GoogleMapsApiKey).
  • Step 1: Add the Dependency

In your pubspec.yaml, add:

dependencies:
  flutter:
    sdk: flutter
  google_maps_flutter: ^2.7.0  # Use the latest version

Run flutter pub get to install.

Step 2: Basic Map Implementation

Create a simple map widget in a Dart file (e.g., lib/map_screen.dart). This sets up the controller needed for theming.

import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'dart:ui' as ui;  // For Brightness enum

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

class _MapScreenState extends State<MapScreen> {
  late GoogleMapController _mapController;
  String? _mapStyle;  // For custom styles

  @override
  void initState() {
    super.initState();
    _loadMapStyle();  // Load custom style if needed
  }

  Future<void> _loadMapStyle() async {
    // Example: Load from assets (detailed below)
    _mapStyle = await DefaultAssetBundle.of(context).loadString('assets/map_styles/custom.json');
  }

  @override
  Widget build(BuildContext context) {
    final ui.Brightness brightness = MediaQuery.of(context).platformBrightness;
    return Scaffold(
      appBar: AppBar(title: const Text('Google Maps Theme')),
      body: GoogleMap(
        onMapCreated: (GoogleMapController controller) {
          _mapController = controller;
          _applyMapStyle(brightness);  // Apply theme
        },
        initialCameraPosition: const CameraPosition(
          target: LatLng(37.7749, -122.4194),  // San Francisco
          zoom: 12.0,
        ),
        mapType: MapType.normal,  // Built-in type (change as needed)
      ),
    );
  }

  void _applyMapStyle(ui.Brightness brightness) {
    if (_mapStyle != null) {
      _mapController.setMapStyle(_mapStyle!);
    }
    // For dynamic dark/light, update style based on brightness
  }

  @override
  void dispose() {
    _mapController.dispose();
    super.dispose();
  }
}

Run the app with flutter run to see a basic map.

Step 3: Using Built-in Map Themes

For quick theming without custom JSON, use the mapType property in GoogleMap. Options include:

  • MapType.normal: Standard roadmap (default).
  • MapType.satellite: Satellite imagery.
  • MapType.terrain: Terrain view.
  • MapType.hybrid: Satellite with labels.
  • MapType.none: No map tiles (for overlays).

Update the GoogleMap widget:

GoogleMap(
  mapType: MapType.terrain,  // Or switch dynamically
  // ... other properties
)

To switch dynamically (e.g., via a button):

FloatingActionButton(
  onPressed: () => _mapController.setMapType(MapType.satellite),
  child: const Icon(Icons.layers),
)

Step 4: Applying Custom Static Map Styles

For branded or unique looks, use JSON styles generated from tools like the Google Maps Styling Wizard (pre-built themes like “Night” or “Aubergine” available) or Snazzy Maps.

  1. Generate the Style:
  • Visit the Styling Wizard, customize elements (e.g., roads, water, labels), and click “Finish” to get JSON.
  1. Add as Asset:
  • Create assets/map_styles/custom.json and paste the JSON (example below).
  • Update pubspec.yaml:
    yaml flutter: assets: - assets/map_styles/
  • Run flutter pub get.
  1. Apply in Code:
  • Load the JSON in initState() (as shown in Step 2’s _loadMapStyle).
  • In onMapCreated, call _mapController.setMapStyle(_mapStyle!);.

Example JSON for a muted style (assets/map_styles/custom.json):

[
  {
    "featureType": "all",
    "elementType": "labels",
    "stylers": [{ "visibility": "off" }]
  },
  {
    "featureType": "road",
    "elementType": "all",
    "stylers": [{ "saturation": -100 }, { "lightness": 50 }]
  },
  {
    "featureType": "water",
    "elementType": "all",
    "stylers": [{ "color": "#beecff" }]
  }
]

Step 5: Dynamic Theme Switching (Dark/Light Mode)

To sync the map with your app’s theme (e.g., system dark mode), generate separate JSONs for light/dark and switch based on MediaQuery.platformBrightness.

  1. Generate Styles:
  • Create assets/map_styles/light.json and assets/map_styles/dark.json using the Styling Wizard (e.g., “Light Monochrome” and “Night” themes).
  1. Load Both Styles:
    Update initState():
   String? _lightStyle, _darkStyle;

   Future<void> _loadMapStyles() async {
     _lightStyle = await DefaultAssetBundle.of(context).loadString('assets/map_styles/light.json');
     _darkStyle = await DefaultAssetBundle.of(context).loadString('assets/map_styles/dark.json');
   }
  1. Apply Dynamically:
    In _applyMapStyle:
   void _applyMapStyle(ui.Brightness brightness) {
     final String style = brightness == ui.Brightness.dark ? _darkStyle! : _lightStyle!;
     _mapController.setMapStyle(style);
   }
  • Listen for theme changes by wrapping your app in ThemeProvider or using WidgetsBindingObserver to rebuild on brightness changes.
  • Call _applyMapStyle in didChangeDependencies for reactivity:
    dart @override void didChangeDependencies() { super.didChangeDependencies(); final brightness = MediaQuery.of(context).platformBrightness; _applyMapStyle(brightness); }

Tips and Troubleshooting

  • Styles apply only after onMapCreated; ensure the controller is ready.
  • Test on physical devices/simulators, as web previews may differ.
  • For more styles, explore Snazzy Maps and copy-paste JSON directly.
  • If styles don’t load, check asset paths and console for errors.

This setup ensures your map integrates seamlessly with your app’s UI. For full examples, check the google_maps_flutter pub.dev page.

Where do these light/dart.json come from

Those light.json and dark.json files are example asset files I referenced in the Flutter code for custom Google Maps styling—they’re not built-in or automatically generated by Flutter or the google_maps_flutter package. Instead, they’re user-created JSON files containing map style rules that you (the developer) generate yourself using free online tools. Here’s a quick breakdown of their origin and how to create them:

What They Represent

  • These are custom map style definitions in JSON format, based on Google Maps’ styling API. Each file defines visual tweaks like colors, visibility, saturation, and lightness for map elements (e.g., roads, water, labels, parks).
  • light.json: A light-themed style (e.g., brighter colors, higher contrast for daytime use).
  • dark.json: A dark-themed style (e.g., muted tones, inverted colors for night mode).
  • They’re stored in your app’s assets/map_styles/ folder and loaded at runtime to apply the theme via _mapController.setMapStyle().

Where to Get/Create Them

You create these from scratch using Google’s official tools or community libraries. No download is needed; just copy-paste the generated JSON into your project files. Recommended sources:

  1. Google Maps Styling Wizard (Official Tool):
  • Go to mapstyle.withgoogle.com.
  • Customize the map interactively: Select elements (e.g., roads, water) from the sidebar, adjust colors/hue/saturation/lightness, and preview live.
  • For light theme: Start with a default or “Pale Dawn” base, then tweak for subtlety (e.g., desaturate grays for roads, light blue for water).
  • For dark theme: Choose “Night” or “Midnight Commander” as a starting point, invert colors (e.g., dark grays for land, deep navy for water).
  • Click “Finish” > “Copy JSON” to get the raw code.
  • Paste it into light.json or dark.json in your assets/ folder. Example light.json output (simplified for a clean, minimalist light theme):
   [
     {
       "featureType": "all",
       "elementType": "geometry",
       "stylers": [{ "color": "#f5f5f5" }]
     },
     {
       "featureType": "road",
       "elementType": "geometry",
       "stylers": [{ "color": "#ffffff" }]
     },
     {
       "featureType": "water",
       "elementType": "geometry",
       "stylers": [{ "color": "#c8d7d0" }]
     },
     {
       "featureType": "landscape",
       "stylers": [{ "color": "#e0e0e0" }]
     }
   ]

Example dark.json output (simplified for a sleek dark mode):

   [
     {
       "featureType": "all",
       "elementType": "geometry",
       "stylers": [{ "color": "#212121" }]
     },
     {
       "featureType": "road",
       "elementType": "geometry",
       "stylers": [{ "color": "#424242" }]
     },
     {
       "featureType": "water",
       "elementType": "geometry",
       "stylers": [{ "color": "#1f3543" }]
     },
     {
       "featureType": "landscape",
       "stylers": [{ "color": "#2c3e50" }]
     }
   ]
  1. Snazzy Maps (Community Gallery):
  • Visit snazzymaps.com and browse/search for “light” or “dark” themes (e.g., “Clean Light” or “Dark Monochrome”).
  • Click on a style > “Edit this map” or “Show JSON code.”
  • Copy the JSON and save it as your .json file.
  • Pro: Hundreds of pre-made, tested styles. Con: Less customization than Google’s wizard.

Next Steps in Your Project

  • After creating the files, ensure they’re declared in pubspec.yaml (as I mentioned before).
  • Test by running the app and toggling themes—Google Maps will render the styles instantly.
  • If you want more advanced options (e.g., runtime generation), you could fetch styles from a server, but assets are simplest for static themes.

Making Google Maps Theme Light-Only in Flutter

Yes, absolutely! You can easily configure your Flutter app to always use a light theme for the Google Map, ignoring the system’s dark mode or any dynamic brightness changes. This is ideal if your app has a fixed light UI or you want a consistent map appearance. We’ll build on the previous code by simplifying the style loading and application—loading only the light.json and applying it unconditionally.

Quick Setup Recap

  • Ensure you have assets/map_styles/light.json with your light theme JSON (generated from Google’s Styling Wizard or Snazzy Maps, as discussed).
  • Declare it in pubspec.yaml under flutter: assets: - assets/map_styles/.

Updated Code: Light-Only Implementation

In your MapScreen (or equivalent), remove dark mode logic and hardcode the light style. Here’s the modified _MapScreenState:

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

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

class _MapScreenState extends State<MapScreen> {
  late GoogleMapController _mapController;
  String? _lightStyle;  // Only light style now

  @override
  void initState() {
    super.initState();
    _loadLightStyle();  // Load only light style
  }

  Future<void> _loadLightStyle() async {
    _lightStyle = await DefaultAssetBundle.of(context).loadString('assets/map_styles/light.json');
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Light-Only Google Maps Theme')),
      body: GoogleMap(
        onMapCreated: (GoogleMapController controller) {
          _mapController = controller;
          _applyLightStyle();  // Always apply light style
        },
        initialCameraPosition: const CameraPosition(
          target: const LatLng(37.7749, -122.4194),  // Example: San Francisco
          zoom: 12.0,
        ),
        mapType: MapType.normal,  // Built-in type; custom style overrides visuals
      ),
    );
  }

  void _applyLightStyle() {
    if (_lightStyle != null) {
      _mapController.setMapStyle(_lightStyle!);
    }
  }

  @override
  void dispose() {
    _mapController.dispose();
    super.dispose();
  }
}

Key Changes and Why They Work

  • Single Style Load: _loadLightStyle() fetches only light.json. No need for _darkStyle or conditional checks.
  • Unconditional Application: _applyLightStyle() always sets the light style in onMapCreated. It ignores MediaQuery.platformBrightness entirely.
  • No Dynamic Updates: Removed didChangeDependencies or any listeners for theme changes, so the map stays light even if the user toggles system dark mode.
  • Fallback to Built-in: If you skip custom JSON, just set mapType: MapType.normal for Google’s default light roadmap—it’s light by nature and doesn’t require assets.

Testing and Tips

  • Run flutter run on a device/simulator. The map should render in your light style immediately after loading.
  • If you want to force even the built-in types to feel “lighter,” combine with mapType: MapType.normal or MapType.terrain.
  • Performance: Loading from assets is fast and offline-friendly. For a truly minimal light theme, use a simple JSON like the one I provided earlier (e.g., light grays and whites).
  • Edge Case: On very old Android devices, styles might not apply smoothly—test on your target SDKs.
  • Jenkins SCP File Upload to Remote Server
  • Essential Programming Books – Principles & Flutter
  • Social Media Platforms 🌍
  • Strategies to prevent review regressions
  • How to set Google Map Theme in a Flutter App

Categories

  • Apps (22)
  • ChatGPT (23)
  • Choosing a Framework (38)
  • Flutter (269)
  • Graphical User Interface (14)
  • Marketing (117)
  • Software Development (286)
  • Spring (45)
  • StartUp (22)
  • Uncategorized (14)
  • Uncategorized (4)
  • Vaadin (15)

Tags

Algorithms (9) crypto (29) flutterdev (39) General (86) Java (7) QR & Bar Codes (3) Software Dev Choices (33) Spring Boot (1) standards (1) Theme (3) User Authentication & Authorization (9) User Experience (10) Utilities (19) WordPress (11)

Product categories

  • All Technologies (84)
    • Flutter Apps (24)
    • GPT (4)
    • Java (38)
    • Native Android (3)
    • PHP (9)
    • Spring (Boot) / Quarkus (35)
    • Utils (15)
    • Vaadin 24+ (27)
    • Vaadin 8 (1)
  • Apps (18)
    • Employees DB (1)
    • Notes (6)
    • Personal Budget (1)
    • Recipes Book (1)
    • Stuff Organizer (1)
    • To-Do (2)
  • PDF Books (3)
  • Source Code Generators (8)

Recent Posts

  • Jenkins SCP File Upload to Remote Server
  • Essential Programming Books – Principles & Flutter
  • Social Media Platforms 🌍
  • Strategies to prevent review regressions
  • How to set Google Map Theme in a Flutter App

Post Categories

  • Apps (22)
  • ChatGPT (23)
  • Choosing a Framework (38)
  • Flutter (269)
  • Graphical User Interface (14)
  • Marketing (117)
  • Software Development (286)
  • Spring (45)
  • StartUp (22)
  • Uncategorized (14)
  • Uncategorized (4)
  • Vaadin (15)