Usando a API do Google Maps em seu aplicativo

Usar o aplicativo Mapas é ótimo, mas às vezes você deseja incluir mapas diretamente em seu aplicativo. Além do aplicativo de mapas interno, o Google também oferece uma API de mapeamento nativo para Android. A API de Mapas é adequada para casos em que você deseja manter mais controle sobre a experiência de mapeamento. As coisas possíveis com a API de Mapas incluem:

  • Alterando programaticamente o ponto de vista do mapa.
  • Adicionar e personalizar marcadores.
  • Anotando um mapa com sobreposições.

Ao contrário da API android v1 do Google Maps agora preterida, a API do Android v2 do Google Maps faz parte do Google Play Services. Um aplicativo Xamarin.Android deve atender a alguns pré-requisitos obrigatórios antes que seja possível usar a API android do Google Maps.

Pré-requisitos da API do Google Mapas

Várias etapas precisam ser executadas antes que você possa usar a API de Mapas, incluindo:

Obter uma chave de API do Google Mapas

A primeira etapa é obter uma chave de API do Google Mapas (observe que você não pode reutilizar uma chave de API da API herdada do Google Mapas v1). Para obter informações sobre como obter e usar a chave de API com o Xamarin.Android, consulte Obtendo uma chave de API do Google Mapas.

Instalar o SDK do Google Play Services

O Google Play Services é uma tecnologia do Google que permite que aplicativos Android aproveitem vários recursos do Google, como Google+, In-App Cobrança e Mapas. Esses recursos são acessíveis em dispositivos Android como serviços em segundo plano, que estão contidos na APK do Google Play Services.

Os aplicativos Android interagem com o Google Play Services por meio da biblioteca de clientes do Google Play Services. Essa biblioteca contém as interfaces e classes para os serviços individuais, como Mapas. O diagrama a seguir mostra a relação entre um aplicativo Android e o Google Play Services:

Diagrama ilustrando a Google Play Store atualizando a APK do Google Play Services

A API do Android Maps é fornecida como parte do Google Play Services. Antes que um aplicativo Xamarin.Android possa usar a API de Mapas, o SDK do Google Play Services deve ser instalado usando o Gerenciador de SDK do Android. A captura de tela a seguir mostra onde, no Gerenciador de SDK do Android, o cliente dos serviços do Google Play pode ser encontrado:

O Google Play Services aparece em Extras no Gerenciador de SDK do Android

Observação

A APK dos serviços do Google Play é um produto licenciado que pode não estar presente em todos os dispositivos. Se ele não estiver instalado, o Google Mapas não funcionará no dispositivo.

Instalar o pacote Xamarin.GooglePlayServices.Maps do NuGet

O pacote Xamarin.GooglePlayServices.Maps contém as associações Xamarin.Android para a API do Google Play Services Maps. Para adicionar o pacote Mapa do Google Play Services, clique com o botão direito do mouse na pasta Referências do seu projeto no Gerenciador de Soluções e clique em Gerenciar Pacotes NuGet...:

Gerenciador de Soluções mostrando o item de menu de contexto Gerenciar Pacotes NuGet em Referências

Isso abre o Gerenciador de Pacotes NuGet. Clique em Procurar e insira Xamarin Google Play Services Mapas no campo de pesquisa. Selecione Xamarin.GooglePlayServices.Maps e clique em Instalar. (Se esse pacote tiver sido instalado anteriormente, clique em Atualizar.):

Gerenciador de Pacotes NuGet com o pacote Xamarin.GooglePlayServices.Maps selecionado

Observe que os seguintes pacotes de dependência também estão instalados:

  • Xamarin.GooglePlayServices.Base
  • Xamarin.GooglePlayServices.Basement
  • Xamarin.GooglePlayServices.Tasks

Especificar as permissões necessárias

Os aplicativos devem identificar os requisitos de hardware e permissão para usar a API do Google Maps. Algumas permissões são concedidas automaticamente pelo SDK do Google Play Services e não é necessário que um desenvolvedor as adicione explicitamente ao AndroidManfest.XML:

  • Acesso ao Estado da Rede – a API de Mapas deve ser capaz de marcar se puder baixar os blocos do mapa.

  • Acesso à Internet – o acesso à Internet é necessário para baixar os blocos de mapa e se comunicar com os Google Play Servers para acesso à API.

As seguintes permissões e recursos devem ser especificados no AndroidManifest.XML para a API android do Google Maps:

  • OpenGL ES v2 – O aplicativo deve declarar o requisito para OpenGL ES v2.

  • Chave de API do Google Mapas – a chave de API é usada para confirmar se o aplicativo está registrado e autorizado a usar o Google Play Services. Consulte Obtendo uma chave de API do Google Mapas para obter detalhes sobre essa chave.

  • Solicite o cliente Apache HTTP herdado – Aplicativos direcionados ao Android 9.0 (nível de API 28) ou superior devem especificar que o cliente Apache HTTP herdado é uma biblioteca opcional a ser usada.

  • Acesso aos Serviços baseados na Web do Google – o aplicativo precisa de permissões para acessar os serviços Web do Google que dão suporte à API do Android Maps.

  • Permissões para Notificações do Google Play Services – O aplicativo deve receber permissão para receber notificações remotas do Google Play Services.

  • Acesso a provedores de localização – são permissões opcionais. Eles permitirão que a GoogleMap classe exiba o local do dispositivo no mapa.

Além disso, o Android 9 removeu a biblioteca de clientes APACHE HTTP do bootclasspath e, portanto, não está disponível para aplicativos direcionados à API 28 ou superior. A linha a seguir deve ser adicionada ao application nó do arquivo AndroidManifest.xml para continuar usando o cliente APACHE HTTP em aplicativos direcionados à API 28 ou superior:

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

Observação

Versões muito antigas do SDK do Google Play exigiam um aplicativo para solicitar a WRITE_EXTERNAL_STORAGE permissão. Esse requisito não é mais necessário com as associações recentes do Xamarin para o Google Play Services.

O snippet a seguir é um exemplo das configurações que devem ser adicionadas ao AndroidManifest.XML:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="4.5" package="com.xamarin.docs.android.mapsandlocationdemo2" android:versionCode="6">
    <uses-sdk android:minSdkVersion="23" android:targetSdkVersion="28" />

    <!-- Google Maps for Android v2 requires OpenGL ES v2 -->
    <uses-feature android:glEsVersion="0x00020000" android:required="true" />

    <!-- Necessary for apps that target Android 9.0 or higher -->
    <uses-library android:name="org.apache.http.legacy" android:required="false" />

    <!-- Permission to receive remote notifications from Google Play Services -->
    <!-- Notice here that we have the package name of our application as a prefix on the permissions. -->
    <uses-permission android:name="<PACKAGE NAME>.permission.MAPS_RECEIVE" />
    <permission android:name="<PACKAGE NAME>.permission.MAPS_RECEIVE" android:protectionLevel="signature" />

    <!-- These are optional, but recommended. They will allow Maps to use the My Location provider. -->
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

    <application android:label="@string/app_name">
        <!-- Put your Google Maps V2 API Key here. -->
        <meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="YOUR_API_KEY" />
        <meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />
        <!-- Necessary for apps that target Android 9.0 or higher -->
        <uses-library android:name="org.apache.http.legacy" android:required="false" />
    </application>
</manifest>

Além de solicitar as permissões AndroidManifest.XML, um aplicativo também deve executar verificações de permissão de runtime para as ACCESS_COARSE_LOCATIONACCESS_FINE_LOCATION permissões e . Consulte o guia Permissões do Xamarin.Android para obter mais informações sobre como executar verificações de permissão em tempo de execução.

Criar um Emulador com APIs do Google

Caso um dispositivo Android físico com serviços Google Play não esteja instalado, é possível criar uma imagem do emulador para desenvolvimento. Para obter mais informações, consulte o Gerenciador de Dispositivos.

A classe GoogleMap

Depois que os pré-requisitos forem atendidos, é hora de começar a desenvolver o aplicativo e usar a API do Android Maps. A classe GoogleMap é a API main que um aplicativo Xamarin.Android usará para exibir e interagir com um Google Maps para Android. Essa classe tem as seguintes responsabilidades:

  • Interagir com os serviços do Google Play para autorizar o aplicativo com o serviço Web do Google.

  • Baixar, armazenar em cache e exibir os blocos do mapa.

  • Exibindo controles de interface do usuário, como pan e zoom para o usuário.

  • Marcadores de desenho e formas geométricas em mapas.

O GoogleMap é adicionado a uma Atividade de duas maneiras:

  • MapFragmentMapFragment é um fragmento especializado que atua como host para o GoogleMap objeto . O MapFragment requer o nível 12 ou superior da API do Android. Versões mais antigas do Android podem usar o SupportMapFragment. Este guia se concentrará em usar a MapFragment classe .

  • MapView – o MapView é uma subclasse de Exibição especializada, que pode atuar como um host para um GoogleMap objeto . Os usuários dessa classe devem encaminhar todos os métodos de ciclo de vida de atividade para a MapView classe .

Cada um desses contêineres expõe uma Map propriedade que retorna uma instância de GoogleMap. A preferência deve ser dada à classe MapFragment , pois é uma API mais simples que reduz a quantidade de código clichê que um desenvolvedor deve implementar manualmente.

Adicionando um MapFragment a uma atividade

A captura de tela a seguir é um exemplo de um simples MapFragment:

Captura de tela de um dispositivo exibindo um fragmento do Mapa do Google

Semelhante a outras classes fragment, há duas maneiras de adicionar um MapFragment a uma Atividade:

  • Declarativamente – o MapFragment pode ser adicionado por meio do arquivo de layout XML para a Atividade. O snippet XML a seguir mostra um exemplo de como usar o fragment elemento :

    <?xml version="1.0" encoding="utf-8"?>
    <fragment xmlns:android="http://schemas.android.com/apk/res/android"
              android:id="@+id/map"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              class="com.google.android.gms.maps.MapFragment" />
    
  • Programaticamente – o MapFragment pode ser instanciado programaticamente usando o MapFragment.NewInstance método e, em seguida, adicionado a uma Atividade. Este snippet mostra a maneira mais simples de instanciar um MapFragment objeto e adicionar a uma Atividade:

        var mapFrag = MapFragment.NewInstance();
        activity.FragmentManager.BeginTransaction()
                                .Add(Resource.Id.map_container, mapFrag, "map_fragment")
                                .Commit();
    
    

    É possível configurar o MapFragment objeto passando um GoogleMapOptions objeto para NewInstance. Isso é discutido na seção Propriedades do GoogleMap que aparecem posteriormente neste guia.

O MapFragment.GetMapAsync método é usado para inicializar o GoogleMap hospedado pelo fragmento e obter uma referência ao objeto de mapa hospedado pelo MapFragment. Esse método usa um objeto que implementa a IOnMapReadyCallback interface .

Essa interface tem um único método, IMapReadyCallback.OnMapReady(MapFragment map) que será invocado quando for possível que o aplicativo interaja com o GoogleMap objeto. O snippet de código a seguir mostra como uma atividade do Android pode inicializar um MapFragment e implementar a IOnMapReadyCallback interface :

public class MapWithMarkersActivity : AppCompatActivity, IOnMapReadyCallback
{
    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);
        SetContentView(Resource.Layout.MapLayout);

        var mapFragment = (MapFragment) FragmentManager.FindFragmentById(Resource.Id.map);
        mapFragment.GetMapAsync(this);

        // remainder of code omitted
    }

    public void OnMapReady(GoogleMap map)
    {
        // Do something with the map, i.e. add markers, move to a specific location, etc.
    }
}

Tipos de mapa

Há cinco tipos diferentes de mapas disponíveis na API do Google Maps:

  • Normal – esse é o tipo de mapa padrão. Mostra estradas e características naturais importantes, juntamente com alguns pontos artificiais de interesse (como edifícios e pontes).

  • Satélite - Este mapa mostra a fotografia por satélite.

  • Híbrido – este mapa mostra fotografia por satélite e mapas rodoviários.

  • Terreno - Isso mostra principalmente características topográficas com algumas estradas.

  • Nenhum – esse mapa não carrega nenhum bloco, ele é renderizado como uma grade vazia.

A imagem abaixo mostra três dos diferentes tipos de mapas, da esquerda para a direita (normal, híbrido, terreno):

Três capturas de tela de exemplo de mapa: Normal, Híbrido e Terreno

A GoogleMap.MapType propriedade é usada para definir ou alterar qual tipo de mapa é exibido. O snippet de código a seguir mostra como exibir um mapa satélite.

public void OnMapReady(GoogleMap map)
{
    map.MapType = GoogleMap.MapTypeHybrid;
}

Propriedades do GoogleMap

GoogleMap define várias propriedades que podem controlar a funcionalidade e a aparência do mapa. Uma maneira de configurar o estado inicial de um GoogleMap é passar um objeto GoogleMapOptions ao criar um MapFragment. O snippet de código a seguir é um exemplo de como usar um GoogleMapOptions objeto ao criar um MapFragment:

GoogleMapOptions mapOptions = new GoogleMapOptions()
    .InvokeMapType(GoogleMap.MapTypeSatellite)
    .InvokeZoomControlsEnabled(false)
    .InvokeCompassEnabled(true);

FragmentTransaction fragTx = FragmentManager.BeginTransaction();
mapFragment = MapFragment.NewInstance(mapOptions);
fragTx.Add(Resource.Id.map, mapFragment, "map");
fragTx.Commit();

A outra maneira de configurar um GoogleMap é manipulando propriedades nas UiSettings do objeto de mapa. O próximo exemplo de código mostra como configurar um GoogleMap para exibir os controles de zoom e uma bússola:

public void OnMapReady(GoogleMap map)
{
    map.UiSettings.ZoomControlsEnabled = true;
    map.UiSettings.CompassEnabled = true;
}

Interagindo com o GoogleMap

A API de Mapas do Android fornece APIs que permitem que uma Atividade altere o ponto de vista, adicione marcadores, coloque sobreposições personalizadas ou desenhe formas geométricas. Esta seção discutirá como realizar algumas dessas tarefas no Xamarin.Android.

Alterando o ponto de vista

Os mapas são modelados como um plano plano na tela, com base na projeção do Mercator. A exibição do mapa é a de uma câmera olhando diretamente para baixo neste plano. A posição da câmera pode ser controlada alterando o local, o zoom, a inclinação e o rolamento. A classe CameraUpdate é usada para mover o local da câmera. CameraUpdate os objetos não são instanciados diretamente, em vez disso, a API mapas fornece a classe CameraUpdateFactory .

Depois que um CameraUpdate objeto é criado, ele é passado como um parâmetro para os métodos GoogleMap.MoveCamera ou GoogleMap.AnimateCamera . O MoveCamera método atualiza o mapa instantaneamente enquanto o AnimateCamera método fornece uma transição suave e animada.

Este snippet de código é um exemplo simples de como usar o CameraUpdateFactory para criar um CameraUpdate que incrementará o nível de zoom do mapa em um nível de zoom:

MapFragment mapFrag = (MapFragment) FragmentManager.FindFragmentById(Resource.Id.my_mapfragment_container);
mapFrag.GetMapAsync(this);
...

public void OnMapReady(GoogleMap map)
{   
    map.MoveCamera(CameraUpdateFactory.ZoomIn());
}

A API de Mapas fornece uma CameraPosition que agregará todos os valores possíveis para a posição da câmera. Uma instância dessa classe pode ser fornecida ao método CameraUpdateFactory.NewCameraPosition que retornará um CameraUpdate objeto . A API de Mapas também inclui a classe CameraPosition.Builder que fornece uma API fluente para criar CameraPosition objetos. O snippet de código a seguir mostra um exemplo de como criar um CameraUpdate de um CameraPosition e usá-lo para alterar a posição da câmera em um GoogleMap:

public void OnMapReady(GoogleMap map)
{
    LatLng location = new LatLng(50.897778, 3.013333);

    CameraPosition.Builder builder = CameraPosition.InvokeBuilder();
    builder.Target(location);
    builder.Zoom(18);
    builder.Bearing(155);
    builder.Tilt(65);

    CameraPosition cameraPosition = builder.Build();

    CameraUpdate cameraUpdate = CameraUpdateFactory.NewCameraPosition(cameraPosition);

    map.MoveCamera(cameraUpdate);
}

No snippet de código anterior, um local específico no mapa é representado pela classe LatLng . O nível de zoom é definido como 18, que é uma medida arbitrária de zoom usada pelo Google Maps. O rolamento é a medida da bússola no sentido horário do Norte. A propriedade Tilt controla o ângulo de exibição e especifica um ângulo de 25 graus da vertical. A captura de tela a seguir mostra o GoogleMap depois de executar o código anterior:

Exemplo do Google Map mostrando um local especificado com um ângulo de exibição inclinado

Desenhando no mapa

A API de Mapas do Android fornece API para desenhar os seguintes itens em um mapa:

  • Marcadores – são ícones especiais que são usados para identificar um único local em um mapa.

  • Sobreposições – essa é uma imagem que pode ser usada para identificar uma coleção de locais ou área no mapa.

  • Linhas, polígonos e círculos – são APIs que permitem que as Atividades adicionem formas a um mapa.

Marcadores

A API de Mapas fornece uma classe Marker que encapsula todos os dados sobre um único local em um mapa. Por padrão, a classe Marker usa um ícone padrão fornecido pelo Google Maps. É possível personalizar a aparência de um marcador e responder a cliques do usuário.

Adicionando um marcador

Para adicionar um marcador a um mapa, é necessário criar um novo objeto MarkerOptions e, em seguida, chamar o método AddMarker em uma GoogleMap instância. Esse método retornará um objeto Marker .

public void OnMapReady(GoogleMap map)
{
    MarkerOptions markerOpt1 = new MarkerOptions();
    markerOpt1.SetPosition(new LatLng(50.379444, 2.773611));
    markerOpt1.SetTitle("Vimy Ridge");

    map.AddMarker(markerOpt1);
}

O título do marcador será exibido em uma janela de informações quando o usuário tocar no marcador. A captura de tela a seguir mostra a aparência desse marcador:

Exemplo do Google Map com um marcador e uma janela de informações para Vimy Ridge

Personalizando um marcador

É possível personalizar o ícone usado pelo marcador chamando o MarkerOptions.InvokeIcon método ao adicionar o marcador ao mapa. Esse método usa um objeto BitmapDescriptor que contém os dados necessários para renderizar o ícone. A classe BitmapDescriptorFactory fornece alguns métodos auxiliares para simplificar a criação de um BitmapDescriptor. A lista a seguir apresenta alguns destes métodos:

  • DefaultMarker(float colour) – Use o marcador padrão do Google Maps, mas altere a cor.

  • FromAsset(string assetName) – Use um ícone personalizado do arquivo especificado na pasta Ativos.

  • FromBitmap(Bitmap image) – Use o bitmap especificado como o ícone.

  • FromFile(string fileName) – Crie o ícone personalizado do arquivo no caminho especificado.

  • FromResource(int resourceId) – Crie um ícone personalizado do recurso especificado.

O snippet de código a seguir mostra um exemplo de criação de um marcador padrão cor de ciano:

public void OnMapReady(GoogleMap map)
{
    MarkerOptions markerOpt1 = new MarkerOptions();
    markerOpt1.SetPosition(new LatLng(50.379444, 2.773611));
    markerOpt1.SetTitle("Vimy Ridge");

    var bmDescriptor = BitmapDescriptorFactory.DefaultMarker (BitmapDescriptorFactory.HueCyan);
    markerOpt1.InvokeIcon(bmDescriptor);

    map.AddMarker(markerOpt1);
}

Janelas de informações

Janelas de informações são janelas especiais que aparecem para exibir informações ao usuário quando ele toca em um marcador específico. Por padrão, a janela de informações exibirá o conteúdo do título do marcador. Se o título não tiver sido atribuído, nenhuma janela de informações será exibida. Somente uma janela de informações pode ser mostrada por vez.

É possível personalizar a janela de informações implementando a interface GoogleMap.IInfoWindowAdapter . Há dois métodos importantes nessa interface:

  • public View GetInfoWindow(Marker marker) – Esse método é chamado para obter uma janela de informações personalizadas para um marcador. Se ele retornar null , a renderização da janela padrão será usada. Se esse método retornar um View, esse Modo de Exibição será colocado dentro do quadro da janela de informações.

  • public View GetInfoContents(Marker marker) – Esse método só será chamado se GetInfoWindow retornar null . Esse método poderá retornar um null valor se a renderização padrão do conteúdo da janela de informações for usada. Caso contrário, esse método deve retornar um View com o conteúdo da janela de informações.

Uma janela de informações não é uma exibição dinâmica – em vez disso, o Android converterá o Modo de Exibição em um bitmap estático e exibirá isso na imagem. Isso significa que uma janela de informações não pode responder a eventos ou gestos de toque, nem se atualizará automaticamente. Para atualizar uma janela de informações, é necessário chamar o método GoogleMap.ShowInfoWindow .

A imagem a seguir mostra alguns exemplos de algumas janelas de informações personalizadas. A imagem à esquerda tem seu conteúdo personalizado, enquanto a imagem à direita tem sua janela e conteúdo personalizados com cantos arredondados:

Janelas de marcador de exemplo para Melbourne, incluindo ícone e população. A janela direita tem cantos arredondados.

GroundOverlays

Ao contrário dos marcadores, que identificam um local específico em um mapa, um GroundOverlay é uma imagem usada para identificar uma coleção de locais ou uma área no mapa.

Adicionando um GroundOverlay

Adicionar uma sobreposição de solo a um mapa é semelhante a adicionar um marcador a um mapa. Primeiro, um objeto GroundOverlayOptions é criado. Esse objeto é então passado como um parâmetro para o GoogleMap.AddGroundOverlay método , que retornará um GroundOverlay objeto . Este snippet de código é um exemplo de como adicionar uma sobreposição de terra a um mapa:

BitmapDescriptor image = BitmapDescriptorFactory.FromResource(Resource.Drawable.polarbear);
GroundOverlayOptions groundOverlayOptions = new GroundOverlayOptions()
    .Position(position, 150, 200)
    .InvokeImage(image);
GroundOverlay myOverlay = googleMap.AddGroundOverlay(groundOverlayOptions);

A captura de tela a seguir mostra essa sobreposição em um mapa:

Mapa de exemplo com uma imagem sobreposta de um urso polar

Linhas, círculos e polígonos

Há três tipos simples de figuras geométricas que podem ser adicionadas a um mapa:

  • Polilinha – trata-se de uma série de segmentos de linha conectados. Ele pode marcar um caminho em um mapa ou criar uma forma geométrica.

  • Círculo – isso desenhará um círculo no mapa.

  • Polígono – é uma forma fechada para marcar áreas em um mapa.

Polilinhas

Uma Polilinha é uma lista de objetos consecutivos LatLng que especificam os vértices de cada segmento de linha. Uma polilinha é criada criando primeiro um PolylineOptions objeto e adicionando os pontos a ele. Em PolylineOption seguida, o objeto é passado para um GoogleMap objeto chamando o AddPolyline método .

PolylineOption rectOptions = new PolylineOption();
rectOptions.Add(new LatLng(37.35, -122.0));
rectOptions.Add(new LatLng(37.45, -122.0));
rectOptions.Add(new LatLng(37.45, -122.2));
rectOptions.Add(new LatLng(37.35, -122.2));
rectOptions.Add(new LatLng(37.35, -122.0)); // close the polyline - this makes a rectangle.

googleMap.AddPolyline(rectOptions);
Círculos

Os círculos são criados pela primeira instância de um objeto CircleOption que especificará o centro e o raio do círculo em metros. O círculo é desenhado no mapa chamando GoogleMap.AddCircle. O snippet de código a seguir mostra como desenhar um círculo:

CircleOptions circleOptions = new CircleOptions ();
circleOptions.InvokeCenter (new LatLng(37.4, -122.1));
circleOptions.InvokeRadius (1000);

googleMap.AddCircle (circleOptions);
Polígonos

Polygons são semelhantes a Polylines, no entanto, eles não estão abertos encerrados. Polygons são um loop fechado e têm seu interior preenchido. Polygons são criados exatamente da mesma maneira que um Polyline, exceto o método GoogleMap.AddPolygon invocado.

Ao contrário de um Polyline, um Polygon é auto-fechamento. O polígono será fechado pelo AddPolygon método desenhando uma linha que conecta o primeiro e o último pontos. O snippet de código a seguir criará um retângulo sólido sobre a mesma área que o snippet de código anterior no Polyline exemplo.

PolygonOptions rectOptions = new PolygonOptions();
rectOptions.Add(new LatLng(37.35, -122.0));
rectOptions.Add(new LatLng(37.45, -122.0));
rectOptions.Add(new LatLng(37.45, -122.2));
rectOptions.Add(new LatLng(37.35, -122.2));
// notice we don't need to close off the polygon

googleMap.AddPolygon(rectOptions);

Respondendo a eventos de usuário

Há três tipos de interações que um usuário pode ter com um mapa:

  • Marcador Clique – o usuário clica em um marcador.

  • Arrastar marcador – o usuário clicou por muito tempo em um mparger

  • Info Window Click - O usuário clicou em uma janela de informações.

Cada um desses eventos será discutido mais detalhadamente abaixo.

Eventos de clique de marcador

O MarkerClicked evento é gerado quando o usuário toca em um marcador. Esse evento aceita um GoogleMap.MarkerClickEventArgs objeto como um parâmetro. Essa classe contém duas propriedades:

  • GoogleMap.MarkerClickEventArgs.Handled – Essa propriedade deve ser definida como true para indicar que o manipulador de eventos consumiu o evento. Se isso for definido como false , o comportamento padrão ocorrerá além do comportamento personalizado do manipulador de eventos.

  • Marker – Essa propriedade é uma referência ao marcador que gerou o MarkerClick evento.

Este snippet de código mostra um exemplo de um MarkerClick que alterará a posição da câmera para um novo local no mapa:

void MapOnMarkerClick(object sender, GoogleMap.MarkerClickEventArgs markerClickEventArgs)
{
    markerClickEventArgs.Handled = true;

    var marker = markerClickEventArgs.Marker;
    if (marker.Id.Equals(gotMauiMarkerId))
    {
        LatLng InMaui = new LatLng(20.72110, -156.44776);

        // Move the camera to look at Maui.
        PositionPolarBearGroundOverlay(InMaui);
        googleMap.AnimateCamera(CameraUpdateFactory.NewLatLngZoom(InMaui, 13));
        gotMauiMarkerId = null;
        polarBearMarker.Remove();
        polarBearMarker = null;
    }
    else
    {
        Toast.MakeText(this, $"You clicked on Marker ID {marker.Id}", ToastLength.Short).Show();
    }
}

Eventos de arrastar marcador

Esse evento é gerado quando o usuário deseja arrastar o marcador. Por padrão, os marcadores não são arrastáveis. Um marcador pode ser definido como arrastável definindo a Marker.Draggable propriedade true como ou invocando o MarkerOptions.Draggable método com true como um parâmetro.

Para arrastar o marcador, o usuário deve primeiro clicar com um clique longo no marcador e, em seguida, o dedo deve permanecer no mapa. Quando o dedo do usuário é arrastado na tela, o marcador se move. Quando o dedo do usuário sair da tela, o marcador permanecerá no local.

A lista a seguir descreve os vários eventos que serão gerados para um marcador arrastável:

  • GoogleMap.MarkerDragStart(object sender, GoogleMap.MarkerDragStartEventArgs e) – Esse evento é gerado quando o usuário arrasta o marcador pela primeira vez.

  • GoogleMap.MarkerDrag(object sender, GoogleMap.MarkerDragEventArgs e) – Esse evento é gerado à medida que o marcador está sendo arrastado.

  • GoogleMap.MarkerDragEnd(object sender, GoogleMap.MarkerDragEndEventArgs e) – Esse evento é gerado quando o usuário termina de arrastar o marcador.

Cada um EventArgs dos contém uma única propriedade chamada P0 que é uma referência ao Marker objeto que está sendo arrastado.

Eventos de Clique da Janela de Informações

Somente uma janela de informações pode ser exibida por vez. Quando o usuário clica em uma janela de informações em um mapa, o objeto de mapa aciona um InfoWindowClick evento. O snippet de código a seguir mostra como conectar um manipulador ao evento:

public void OnMapReady(GoogleMap map)
{
    map.InfoWindowClick += MapOnInfoWindowClick;
}

private void MapOnInfoWindowClick (object sender, GoogleMap.InfoWindowClickEventArgs e)
{
    Marker myMarker = e.Marker;
    // Do something with marker.
}

Lembre-se de que uma janela de informações é uma estática View que é renderizada como uma imagem no mapa. Todos os widgets, como botões, caixas de marcar ou modos de exibição de texto colocados dentro da janela de informações, serão inertes e não poderão responder a nenhum dos eventos integrais do usuário.