Skip to content

Disable Scroll Zoom in Flutter

This tutorial shows how to disable or control zoom gestures on your MapMetrics Flutter map. This is useful for maps embedded in scrollable pages where pinch-to-zoom conflicts with page scrolling.

Prerequisites

Before you begin, ensure you have:

Disable Zoom Gestures

Disable pinch-to-zoom and double-tap-to-zoom at initialization:

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

class DisableZoomScreen extends StatefulWidget {
  @override
  _DisableZoomScreenState createState() => _DisableZoomScreenState();
}

class _DisableZoomScreenState extends State<DisableZoomScreen> {
  MapMetricsController? mapController;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Zoom Disabled')),
      body: MapMetrics(
        styleUrl: 'https://gateway.mapmetrics.org/styles/YOUR_STYLE_ID?token=YOUR_API_KEY',
        onMapCreated: (controller) => mapController = controller,
        initialCameraPosition: CameraPosition(
          target: LatLng(48.8566, 2.3522),
          zoom: 13.0,
        ),
        zoomGesturesEnabled: false,  // Disables pinch-to-zoom
      ),
    );
  }
}

The map displays normally but users cannot zoom with gestures. You can still zoom programmatically with buttons.

Disable All Gestures

Lock the map completely — no pan, zoom, or rotation:

dart
MapMetrics(
  styleUrl: 'https://gateway.mapmetrics.org/styles/YOUR_STYLE_ID?token=YOUR_API_KEY',
  onMapCreated: (controller) => mapController = controller,
  initialCameraPosition: CameraPosition(
    target: LatLng(48.8566, 2.3522),
    zoom: 13.0,
  ),
  zoomGesturesEnabled: false,
  scrollGesturesEnabled: false,
  rotateGesturesEnabled: false,
  tiltGesturesEnabled: false,
)

Toggle Zoom On/Off

Let users enable or disable zoom with a switch:

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

class ToggleZoomScreen extends StatefulWidget {
  @override
  _ToggleZoomScreenState createState() => _ToggleZoomScreenState();
}

class _ToggleZoomScreenState extends State<ToggleZoomScreen> {
  MapMetricsController? mapController;
  bool zoomEnabled = true;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Toggle Zoom'),
        actions: [
          Row(
            children: [
              Text(
                zoomEnabled ? 'Zoom ON' : 'Zoom OFF',
                style: TextStyle(color: Colors.white),
              ),
              Switch(
                value: zoomEnabled,
                onChanged: (value) {
                  setState(() {
                    zoomEnabled = value;
                  });
                },
                activeColor: Colors.white,
              ),
            ],
          ),
        ],
      ),
      body: MapMetrics(
        styleUrl: 'https://gateway.mapmetrics.org/styles/YOUR_STYLE_ID?token=YOUR_API_KEY',
        onMapCreated: (controller) => mapController = controller,
        initialCameraPosition: CameraPosition(
          target: LatLng(48.8566, 2.3522),
          zoom: 13.0,
        ),
        zoomGesturesEnabled: zoomEnabled,
      ),
    );
  }
}

Embedded Map in Scrollable Page

A common pattern: disable gestures on an embedded map, then provide a "tap to interact" overlay:

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

class EmbeddedMapScreen extends StatefulWidget {
  @override
  _EmbeddedMapScreenState createState() => _EmbeddedMapScreenState();
}

class _EmbeddedMapScreenState extends State<EmbeddedMapScreen> {
  MapMetricsController? mapController;
  bool isMapActive = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Embedded Map')),
      body: SingleChildScrollView(
        child: Column(
          children: [
            // Some content above the map
            Container(
              padding: EdgeInsets.all(20),
              child: Text(
                'Scroll down to see the map. Tap the map to interact with it.',
                style: TextStyle(fontSize: 16),
              ),
            ),
            // Embedded map with tap-to-activate
            Container(
              height: 300,
              margin: EdgeInsets.all(16),
              clipBehavior: Clip.hardEdge,
              decoration: BoxDecoration(
                borderRadius: BorderRadius.circular(12),
                border: Border.all(color: Colors.grey[300]!),
              ),
              child: Stack(
                children: [
                  MapMetrics(
                    styleUrl: 'https://gateway.mapmetrics.org/styles/YOUR_STYLE_ID?token=YOUR_API_KEY',
                    onMapCreated: (controller) => mapController = controller,
                    initialCameraPosition: CameraPosition(
                      target: LatLng(48.8566, 2.3522),
                      zoom: 13.0,
                    ),
                    zoomGesturesEnabled: isMapActive,
                    scrollGesturesEnabled: isMapActive,
                    rotateGesturesEnabled: isMapActive,
                  ),
                  // Overlay: tap to activate
                  if (!isMapActive)
                    GestureDetector(
                      onTap: () {
                        setState(() {
                          isMapActive = true;
                        });
                      },
                      child: Container(
                        color: Colors.transparent,
                        alignment: Alignment.center,
                        child: Container(
                          padding: EdgeInsets.symmetric(
                            horizontal: 16,
                            vertical: 10,
                          ),
                          decoration: BoxDecoration(
                            color: Colors.black54,
                            borderRadius: BorderRadius.circular(8),
                          ),
                          child: Text(
                            'Tap to interact with map',
                            style: TextStyle(color: Colors.white),
                          ),
                        ),
                      ),
                    ),
                ],
              ),
            ),
            // More content below
            Container(
              padding: EdgeInsets.all(20),
              child: Text(
                'More content below the map...',
                style: TextStyle(fontSize: 16),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

Gesture Properties

PropertyTypeDefaultDescription
zoomGesturesEnabledbooltruePinch-to-zoom and double-tap zoom
scrollGesturesEnabledbooltruePan/drag to move the map
rotateGesturesEnabledbooltrueTwo-finger rotation
tiltGesturesEnabledbooltrueTwo-finger tilt for 3D perspective

Next Steps


Tip: When embedding a map in a scrollable page, always disable scroll gestures so the page scroll works normally. Provide a "tap to interact" overlay to let users opt in.