Xamarin.Forms Map

Download Sample Download the sample

Xamarin.Forms uses the native map APIs on each platform.

Xamarin.Forms.Maps uses the native map APIs on each platform. This provides a fast, familiar maps experience for users, but means that some configuration steps are needed to adhere to each platforms API requirements. Once configured, the Map control works just like any other Xamarin.Forms element in common code.

The map control has been used in the MapsSample sample, which is shown below.

Maps in the MobileCRM sample

Map functionality can be further enhanced by creating a map custom renderer.

Map initialization

When adding maps to a Xamarin.Forms application, Xamarin.Forms.Maps is a separate NuGet package that you should add to every project in the solution. On Android, this also has a dependency on GooglePlayServices (another NuGet) which is downloaded automatically when you add Xamarin.Forms.Maps.

After installing the NuGet package, some initialization code is required in each application project, after the Xamarin.Forms.Forms.Init method call. For iOS use the following code:


On Android you must pass the same parameters as Forms.Init:

Xamarin.FormsMaps.Init(this, bundle);

For the Universal Windows Platform (UWP) use the following code:


Add this call in the following files for each platform:

  • iOS - AppDelegate.cs file, in the FinishedLaunching method.
  • Android - MainActivity.cs file, in the OnCreate method.
  • UWP - MainPage.xaml.cs file, in the MainPage constructor.

Once the NuGet package has been added and the initialization method called inside each application, Xamarin.Forms.Maps APIs can be used in the common .NET Standard library project or Shared Project code.

Platform configuration

Additional configuration steps are required on some platforms before the map will display.


To access location services on iOS, you must set the following keys in Info.plist:

To support iOS 11 and earlier, you can include all three keys: NSLocationWhenInUseUsageDescription, NSLocationAlwaysAndWhenInUseUsageDescription, and NSLocationAlwaysUsageDescription.

The XML representation for these keys in Info.plist is shown below. You should update the string values to reflect how your application is using the location information:

<string>Can we use your location at all times?</string>
<string>Can we use your location when your app is being used?</string>
<string>Can we use your location at all times?</string>

The Info.plist entries can also be added in Source view while editing the Info.plist file:

Info.plist for iOS 8


To use the Google Maps API v2 on Android you must generate an API key and add it to your Android project. Follow the instructions in the Xamarin doc on obtaining a Google Maps API v2 key. After following those instructions, paste the API key in the Properties/AndroidManifest.xml file (view source and find/update the following element):

<application ...>
    <meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="YOUR_API_KEY" />

Without a valid API key the maps control will display as a gray box on Android.


Note that, in order for your APK to access Google Maps, you must include SHA-1 fingerprints and package names for every keystore (debug and release) that you use to sign your APK. For example, if you use one computer for debug and another computer for generating the release APK, you should include the SHA-1 certificate fingerprint from the debug keystore of the first computer and the SHA-1 certificate fingerprint from the release keystore of the second computer. Also remember to edit the key credentials if the app's Package Name changes. See obtaining a Google Maps API v2 key.

You'll also need to enable appropriate permissions by right-clicking on the Android project and selecting Options > Build > Android Application and ticking the following:

  • AccessCoarseLocation
  • AccessFineLocation
  • AccessLocationExtraCommands
  • AccessMockLocation
  • AccessNetworkState
  • AccessWifiState
  • Internet

Some of these are shown in the screenshot below:

Required permissions for Android

The last two are required because applications require a network connection to download map data. Read about Android permissions to learn more.

In addition, Android 9 has removed the Apache HTTP client library from the bootclasspath, and so it isn't available to applications that target API 28 or higher. The following line must be added to the application node of your AndroidManifest.xml file to continue using the Apache HTTP client in applications that target API 28 or higher:

<application ...>
    <uses-library android:name="org.apache.http.legacy" android:required="false" />    

Universal Windows Platform

To use maps on the Universal Windows Platform you must generate an authorization token. For more information, see Request a maps authentication key on MSDN.

The authentication token should then be specified in the FormsMaps.Init("AUTHORIZATION_TOKEN") method call, to authenticate the app with Bing Maps.

Map configuration

See the MapPage.cs in the MobileCRM sample for an example of how the map control can be used in code. A simple MapPage class might look like this - notice that a new MapSpan is created to position the map's view:

public class MapPage : ContentPage {
    public MapPage() {
        var map = new Map(
                    new Position(37,-122), Distance.FromMiles(0.3))) {
                IsShowingUser = true,
                HeightRequest = 100,
                WidthRequest = 960,
                VerticalOptions = LayoutOptions.FillAndExpand
        var stack = new StackLayout { Spacing = 0 };
        Content = stack;

Map type

The map content can also be changed by setting the MapType property, to show a regular street map (the default), satellite imagery or a combination of both.

map.MapType = MapType.Street;

Valid MapType values are:

  • Hybrid
  • Satellite
  • Street (the default)

Map region and MapSpan

As shown in the code snippet above, supplying a MapSpan instance to a map constructor sets the initial view (center point and zoom level) of the map when it is loaded. There are two ways to create a new MapSpan instance:

  • MapSpan.FromCenterAndRadius() - static method to create a span from a Position and specifying a Distance .
  • new MapSpan () - constructor that uses a Position and the degrees of latitude and longitude to display.

The MoveToRegion method on the map class can then be used to change the position or zoom level of the map. To change the zoom level of the map without altering the location, create a new MapSpan using the current location from the VisibleRegion.Center property of the map control. A Slider can be used to control map zoom like this (however zooming directly in the map control cannot currently update the value of the slider):

Slider slider = new Slider (1, 18, 1);
slider.ValueChanged += (sender, e) =>
    var zoomLevel = e.NewValue; // between 1 and 18
    var latlongdegrees = 360 / (Math.Pow(2, zoomLevel));
    map.MoveToRegion(new MapSpan (map.VisibleRegion.Center, latlongdegrees, latlongdegrees));

Maps with zoom

In addition, the Map class has a MoveToLastRegionOnLayoutChange property of type bool, which is backed by a bindable property. By default this property is true, which indicates that the displayed map region will move from its current region to its previously set region when a layout change occurs, such as on device rotation. When this property is set to false, the displayed map region will remain centered when a layout change occurs. The following example shows setting this property:

map.MoveToLastRegionOnLayoutChange = false;

Map pins

Locations can be marked on the map with Pin objects.

var position = new Position(37,-122); // Latitude, Longitude
var pin = new Pin {
            Type = PinType.Place,
            Position = position,
            Label = "custom pin",
            Address = "custom detail info"

PinType can be set to one of the following values, which may affect the way the pin is rendered (depending on the platform):

  • Generic
  • Place
  • SavedPin
  • SearchResult

Map clicks

Map defines a MapClicked event that's fired when the map is tapped. The MapClickedEventArgs object that accompanies the MapClicked event has a single property named Position, of type Position. When the event is fired, the value of the Position property is set to the map location that was tapped.

The following code example shows an event handler for the MapClicked event:

map.MapClicked += OnMapClicked;

void OnMapClicked(object sender, MapClickedEventArgs e)
    System.Diagnostics.Debug.WriteLine($"MapClick: {e.Position.Latitude}, {e.Position.Longitude}");

In this example, the OnMapClicked event handler outputs the latitude and longitude that represents the tapped map location.

Create a Map in XAML

Maps can also be created in XAML, as shown in this example:

<?xml version="1.0" encoding="UTF-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
    <StackLayout VerticalOptions="StartAndExpand" Padding="30">
        <maps:Map x:Name="MyMap"
                  MapType="Hybrid" />


An additional xmlns namespace definition is required to reference the Xamarin.Forms.Maps controls.

The MapRegion and Pins can be set in code using the named reference for the Map:

        new Position(37,-122), Distance.FromMiles(1)));

Populate a Map with data using data binding

The Map class also exposes the following properties:

  • ItemsSource – specifies the collection of IEnumerable items to be displayed.
  • ItemTemplate – specifies the DataTemplate to apply to each item in the collection of displayed items.
  • ItemTemplateSelector – specifies the DataTemplateSelector that will be used to choose a DataTemplate for an item at runtime.


The ItemTemplate property takes precedence when both the ItemTemplate and ItemTemplateSelector properties are set.

A Map can be populated with data by using data binding to bind its ItemsSource property to an IEnumerable collection:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
        <maps:Map x:Name="map"
                  ItemsSource="{Binding Locations}">
                    <maps:Pin Position="{Binding Position}"
                              Address="{Binding Address}"
                              Label="{Binding Description}" />

The ItemsSource property data binds to the Locations property of the connected view model, which returns an ObservableCollection of Location objects, which is a custom type. Each Location object defines Address and Description properties, of type string, and a Position property, of type Position.

The appearance of each item in the IEnumerable collection is defined by setting the ItemTemplate property to a DataTemplate that contains a Pin object that data binds to appropriate properties.

The following screenshots show a Map displaying a Pin collection using data binding:

Screenshot of map with data bound pins, on iOS and Android

Choose item appearance at runtime

The appearance of each item in the IEnumerable collection can be chosen at runtime, based on the item value, by setting the ItemTemplateSelector property to a DataTemplateSelector:

<ContentPage ...
        <local:MapItemTemplateSelector x:Key="MapItemTemplateSelector">
                    <maps:Pin Position="{Binding Position}"
                              Address="{Binding Address}"
                              Label="{Binding Description}" />
                    <maps:Pin Position="{Binding Position}"
                              Address="{Binding Address}"
                              Label="Xamarin!" />

        <maps:Map x:Name="map"
                  ItemsSource="{Binding Locations}"
                  ItemTemplateSelector="{StaticResource MapItemTemplateSelector}" />

The following example shows the MapItemTemplateSelector class:

public class MapItemTemplateSelector : DataTemplateSelector
    public DataTemplate DefaultTemplate { get; set; }
    public DataTemplate XamarinTemplate { get; set; }

    protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
        return ((Location)item).Address.Contains("San Francisco") ? XamarinTemplate : DefaultTemplate;

The MapItemTemplateSelector class defines DefaultTemplate and XamarinTemplate DataTemplate properties that are set to different data templates. The OnSelectTemplate method returns the XamarinTemplate, which displays "Xamarin" as a label when a Pin is tapped, when the item has an address that contains "San Francisco". When the item doesn't have an address that contains "San Francisco", the OnSelectTemplate method returns the DefaultTemplate.

For more information about data template selectors, see Creating a Xamarin.Forms DataTemplateSelector.