Shape Selection in Flutter Maps (SfMaps)

18 Nov 201817 minutes to read

You can select a shape to highlight a specific area on a Flutter Maps. You can also use callbacks to perform custom actions during shape selection.

Enable shape selection

You can enable shape selection on a Flutter Maps using the MapShapeLayer.onSelectionChanged property along with setting the selectedIndex property. The default value of the selectedIndex property is -1.

The onSelectionChanged callback is triggered when a user selects a shape by tapping or clicking, or when a shape is selected programmatically. It provides the index of the selected shape.

You must update the selectedIndex in the MapShapeLayer.onSelectionChanged callback to reflect the changes in the UI.

import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_maps/maps.dart';

class MapsExample extends StatefulWidget {
  @override
  _MapsExampleState createState() => _MapsExampleState();
}

class _MapsExampleState extends State<MapsExample> {
  late List<Model> data;
  late MapShapeSource dataSource;
  int selectedIndex = 1;

  @override
  void initState() {
      super.initState();
      data = const <Model>[
          Model('Asia', 'Asia', Color.fromRGBO(60, 120, 255, 0.8)),
          Model('Africa', 'Africa', Color.fromRGBO(51, 102, 255, 0.8)),
          Model('Europe', 'Europe', Color.fromRGBO(0, 57, 230, 0.8)),
          Model('South America', 'SA', Color.fromRGBO(0, 51, 204, 0.8)),
          Model('Australia', 'Australia', Color.fromRGBO(0, 45, 179, 0.8)),
          Model('North America', 'NA', Color.fromRGBO(0, 38, 153, 0.8))
      ];

      dataSource = MapShapeSource.asset(
        "assets/world_map.json",
         shapeDataField: "continent",
         dataCount: data.length,
         primaryValueMapper: (int index) => data[index].continent,
         shapeColorValueMapper: (int index) => data[index].color,
      );
  }

  @override
  Widget build(BuildContext context) {
     return Scaffold(
        body: Center(
          child: Container(
            height: 350,
            child: Padding(
              padding: EdgeInsets.only(left: 15, right: 15),
              child: SfMaps(
                layers: [
                  MapShapeLayer(
                     source: dataSource,
                     selectedIndex: selectedIndex,
                     onSelectionChanged: (int index) {
                       setState(() {
                          selectedIndex = index;
                       });
                     },
                  ),
                ],
              ),
            ),
          ),
        ),
     );
  }
}

class Model {
  const Model(this.continent, this.code, this.color);

  final String continent;
  final String code;
  final Color color;
}

Enable shape selection

Appearance customization

You can customize the following aspects of the selected shape:

import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_maps/maps.dart';

class MapsExample extends StatefulWidget {
  @override
  _MapsExampleState createState() => _MapsExampleState();
}

class _MapsExampleState extends State<MapsExample> {
  late List<Model> data;
  late MapShapeSource dataSource;
  int selectedIndex = 5;

  @override
  void initState() {
      super.initState();
      data = const <Model>[
          Model('Asia', 'Asia', Color.fromRGBO(60, 120, 255, 0.8)),
          Model('Africa', 'Africa', Color.fromRGBO(51, 102, 255, 0.8)),
          Model('Europe', 'Europe', Color.fromRGBO(0, 57, 230, 0.8)),
          Model('South America', 'SA', Color.fromRGBO(0, 51, 204, 0.8)),
          Model('Australia', 'Australia', Color.fromRGBO(0, 45, 179, 0.8)),
          Model('North America', 'NA', Color.fromRGBO(0, 38, 153, 0.8))
      ];

      dataSource = MapShapeSource.asset(
        "assets/world_map.json",
         shapeDataField: "continent",
         dataCount: data.length,
         primaryValueMapper: (int index) => data[index].continent,
         shapeColorValueMapper: (int index) => data[index].color,
      );
  }

  @override
  Widget build(BuildContext context) {
     return Scaffold(
        body: Center(
          child: Container(
            height: 350,
            child: Padding(
              padding: EdgeInsets.only(left: 15, right: 15),
              child: SfMaps(
                layers: [
                  MapShapeLayer(
                     source: dataSource,
                     selectedIndex: selectedIndex,
                     onSelectionChanged: (int index) {
                       setState(() {
                          selectedIndex = index;
                       });
                     },
                     selectionSettings: MapSelectionSettings(
                        color: Colors.orange,
                        strokeColor: Colors.red[900],
                        strokeWidth: 3,
                     ),
                  ),
                ],
              ),
            ),
          ),
        ),
     );
  }
}

class Model {
  const Model(this.continent, this.code, this.color);

  final String continent;
  final String code;
  final Color color;
}

Using SfMapsTheme

You can also customize the appearance of the selected shape using SfMapsTheme:

You must import the theme.dart library from the Core package to use SfMapsTheme.

import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_maps/maps.dart';
import 'package:syncfusion_flutter_core/theme.dart';

class MapsExample extends StatefulWidget {
  @override
  _MapsExampleState createState() => _MapsExampleState();
}

class _MapsExampleState extends State<MapsExample> {
  late List<Model> data;
  late MapShapeSource dataSource;
  int selectedIndex = 5;

  @override
  void initState() {
      super.initState();
      data = const <Model>[
          Model('Asia', 'Asia', Color.fromRGBO(60, 120, 255, 0.8)),
          Model('Africa', 'Africa', Color.fromRGBO(51, 102, 255, 0.8)),
          Model('Europe', 'Europe', Color.fromRGBO(0, 57, 230, 0.8)),
          Model('South America', 'SA', Color.fromRGBO(0, 51, 204, 0.8)),
          Model('Australia', 'Australia', Color.fromRGBO(0, 45, 179, 0.8)),
          Model('North America', 'NA', Color.fromRGBO(0, 38, 153, 0.8))
      ];

      dataSource = MapShapeSource.asset(
        "assets/world_map.json",
         shapeDataField: "continent",
         dataCount: data.length,
         primaryValueMapper: (int index) => data[index].continent,
         shapeColorValueMapper: (int index) => data[index].color,
      );
  }

  @override
  Widget build(BuildContext context) {
      return Scaffold(
        body: Center(
          child: Container(
            height: 350,
            child: Padding(
              padding: EdgeInsets.only(left: 15, right: 15),
              child: SfMapsTheme(
                data: SfMapsThemeData(
                  selectionColor: Colors.orange,
                  selectionStrokeWidth: 3,
                  selectionStrokeColor: Colors.red[900],
                ),
                child: SfMaps(
                  layers: [
                    MapShapeLayer(
                       source: dataSource,
                       selectedIndex: selectedIndex,
                       onSelectionChanged: (int index) {
                          setState(() {
                             selectedIndex = index;
                          });
                       },
                    ),
                  ],
                ),
              )
            ),
          ),
        ),
     );
  }
}

class Model {
  const Model(this.continent, this.code, this.color);

  final String continent;
  final String code;
  final Color color;
}

Selection customization

You can refer to our Flutter Maps feature tour page for its groundbreaking feature representations. You can also explore our Flutter Maps Selection example that shows how to configure a Maps in Flutter.