Skip to content

Toggle Map Interactions in Flutter

This tutorial shows how to enable and disable individual map interactions like zoom, pan, rotate, and tilt at runtime.

Prerequisites

Before you begin, ensure you have:

Complete Example: Interaction Control Panel

A full control panel that lets users toggle each gesture type independently:

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

class ToggleInteractionsScreen extends StatefulWidget {
  @override
  _ToggleInteractionsScreenState createState() => _ToggleInteractionsScreenState();
}

class _ToggleInteractionsScreenState extends State<ToggleInteractionsScreen> {
  MapMetricsController? mapController;

  bool zoomGestures = true;
  bool scrollGestures = true;
  bool rotateGestures = true;
  bool tiltGestures = true;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Toggle Interactions'),
        actions: [
          TextButton(
            onPressed: _enableAll,
            child: Text('All ON', style: TextStyle(color: Colors.white)),
          ),
          TextButton(
            onPressed: _disableAll,
            child: Text('All OFF', style: TextStyle(color: Colors.white70)),
          ),
        ],
      ),
      body: Column(
        children: [
          // Interaction toggles
          Container(
            padding: EdgeInsets.symmetric(horizontal: 8, vertical: 4),
            color: Colors.grey[100],
            child: Column(
              children: [
                _interactionToggle(
                  'Zoom (pinch)',
                  Icons.zoom_in,
                  zoomGestures,
                  (v) => setState(() => zoomGestures = v),
                ),
                _interactionToggle(
                  'Scroll (pan)',
                  Icons.pan_tool,
                  scrollGestures,
                  (v) => setState(() => scrollGestures = v),
                ),
                _interactionToggle(
                  'Rotate (two-finger)',
                  Icons.rotate_right,
                  rotateGestures,
                  (v) => setState(() => rotateGestures = v),
                ),
                _interactionToggle(
                  'Tilt (two-finger vertical)',
                  Icons.view_in_ar,
                  tiltGestures,
                  (v) => setState(() => tiltGestures = v),
                ),
              ],
            ),
          ),
          // Map
          Expanded(
            child: 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: zoomGestures,
              scrollGesturesEnabled: scrollGestures,
              rotateGesturesEnabled: rotateGestures,
              tiltGesturesEnabled: tiltGestures,
            ),
          ),
        ],
      ),
    );
  }

  Widget _interactionToggle(
    String label,
    IconData icon,
    bool value,
    ValueChanged<bool> onChanged,
  ) {
    return SwitchListTile(
      title: Row(
        children: [
          Icon(icon, size: 20, color: value ? Colors.blue : Colors.grey),
          SizedBox(width: 8),
          Text(label, style: TextStyle(fontSize: 14)),
        ],
      ),
      value: value,
      onChanged: onChanged,
      dense: true,
      contentPadding: EdgeInsets.symmetric(horizontal: 8),
    );
  }

  void _enableAll() {
    setState(() {
      zoomGestures = true;
      scrollGestures = true;
      rotateGestures = true;
      tiltGestures = true;
    });
  }

  void _disableAll() {
    setState(() {
      zoomGestures = false;
      scrollGestures = false;
      rotateGestures = false;
      tiltGestures = false;
    });
  }
}

Presentation Mode

A common use case: lock all interactions for a presentation or kiosk display, then unlock with a button:

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

class PresentationModeScreen extends StatefulWidget {
  @override
  _PresentationModeScreenState createState() => _PresentationModeScreenState();
}

class _PresentationModeScreenState extends State<PresentationModeScreen> {
  MapMetricsController? mapController;
  bool isLocked = true;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: 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: !isLocked,
            scrollGesturesEnabled: !isLocked,
            rotateGesturesEnabled: !isLocked,
            tiltGesturesEnabled: !isLocked,
          ),
          // Lock indicator and toggle
          Positioned(
            top: 50,
            right: 16,
            child: GestureDetector(
              onTap: () => setState(() => isLocked = !isLocked),
              child: Container(
                padding: EdgeInsets.symmetric(horizontal: 12, vertical: 8),
                decoration: BoxDecoration(
                  color: isLocked ? Colors.red : Colors.green,
                  borderRadius: BorderRadius.circular(20),
                  boxShadow: [BoxShadow(color: Colors.black26, blurRadius: 4)],
                ),
                child: Row(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    Icon(
                      isLocked ? Icons.lock : Icons.lock_open,
                      color: Colors.white,
                      size: 16,
                    ),
                    SizedBox(width: 6),
                    Text(
                      isLocked ? 'Locked' : 'Unlocked',
                      style: TextStyle(color: Colors.white, fontSize: 13),
                    ),
                  ],
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

Interaction Properties Reference

PropertyGestureDefault
zoomGesturesEnabledPinch-to-zoom, double-tap zoomtrue
scrollGesturesEnabledDrag/pan to move the maptrue
rotateGesturesEnabledTwo-finger rotationtrue
tiltGesturesEnabledTwo-finger vertical swipe (3D tilt)true

Next Steps


Tip: When disabling gestures, always provide alternative controls (buttons, sliders) so users can still navigate the map.