API do Google Maps v2: como tornar marcadores clicáveis?

128

Como fazer com que os marcadores na API do Google Maps para Android v2 se tornem clicáveis, para abrir um menu com opções ou apenas iniciar uma nova atividade? Acredito que fiz os marcadores no meu aplicativo atualmente em um método "newb". Não atribuai a eles um nome ou um método para poder vinculá-lo ao restante do código necessário.

googleMap.addMarker(new MarkerOptions()
        .position(latLng)
        .title("My Spot")
        .snippet("This is my spot!")
        .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE)));

Se você responder isso, inclua um código de exemplo de um marcador que está sendo introduzido com um nome exclusivo e, em seguida, definido como clicável para abrir uma nova atividade.

Malaka
fonte

Respostas:

238

Todos os marcadores no Google Android Maps Api v2 são clicáveis. Você não precisa definir propriedades adicionais para o seu marcador. O que você precisa fazer - é registrar o retorno de chamada de clique do marcador no seu googleMap e manipular o clique no retorno de chamada:

public class MarkerDemoActivity extends android.support.v4.app.FragmentActivity
    implements OnMarkerClickListener
{
    private Marker myMarker;    

    private void setUpMap()
    {
        .......
        googleMap.setOnMarkerClickListener(this);

        myMarker = googleMap.addMarker(new MarkerOptions()
                    .position(latLng)
                    .title("My Spot")
                    .snippet("This is my spot!")
                    .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE)));
        ......
    }

    @Override
    public boolean onMarkerClick(final Marker marker) {

        if (marker.equals(myMarker)) 
        {
            //handle click here
        }
    }
}

aqui está um bom guia no google sobre personalização de marcadores

Pavel Dudka
fonte
9
Existe uma maneira de ouvir cliques na janela pop-up? Aquele que exibe seu título / snippet?
40
a mesma coisa que com marcadores - você precisa se registrar OnInfoWindowClickListenerCallback. Existe um método em GoogleMap para isso:googleMap.setOnInfoWindowClickListener(listener);
Pavel Dudka
Está tudo funcionando muito bem por enquanto, notei que meu erro não foi defini-lo como uma variável anteriormente no código. Eu simplesmente esqueci o ";" e o código implementado
Malaka
1
@JDOaktown, você precisa dessa verificação se tiver uma lógica diferente para marcadores diferentes. Digamos que você queira mostrar um brinde somente quando um marcador específico for clicado. Se você tem a mesma lógica de tratamento para todos os seus marcadores - Você não precisa marcador cheque
Pavel Dudka
1
Conforme mencionado na documentação ( developers.google.com/android/reference/com/google/android/gms/… ), você precisa retornar true se o clique foi consumido. Se você retornar false - comportamento padrão irá ocorrer
Pavel Dudka
36

setTag(position) ao adicionar marcador ao mapa.

Marker marker =  map.addMarker(new MarkerOptions()
                .position(new LatLng(latitude, longitude)));
marker.setTag(position);

getTag()no setOnMarkerClickListenerouvinte

map.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
                @Override
                public boolean onMarkerClick(Marker marker) {
                    int position = (int)(marker.getTag());
                   //Using position get Value from arraylist 
                    return false;
                }
            });
Parag Chauhan
fonte
4

Evite usar o OnMarkerClickListener dos implementos Activity, use um OnMarkerClickListener local

// Not a good idea
class MapActivity extends Activity implements OnMarkerClickListener {
}

Você precisará de um mapa para procurar o modelo de dados original vinculado ao marcador

private Map<Marker, Map<String, Object>> markers = new HashMap<>();

Você precisará de um modelo de dados

private Map<String, Object> dataModel = new HashMap<>();

Coloque alguns dados no modelo de dados

dataModel.put("title", "My Spot");
dataModel.put("snipet", "This is my spot!");
dataModel.put("latitude", 20.0f);
dataModel.put("longitude", 100.0f);

Ao criar um novo marcador usando um modelo de dados, adicione ambos ao mapa do criador

Marker marker = googleMap.addMarker(markerOptions);
markers.put(marker, dataModel);

Para um evento de marcador de clique, use um OnMarkerClickListener local:

@Override
public void onMapReady(GoogleMap googleMap) {
    // grab for laters
    this.googleMap = googleMap;

    googleMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
        @Override
        public boolean onMarkerClick(Marker marker) {
            Map dataModel = (Map)markers.get(marker);
            String title = (String)dataModel.get("title");
            markerOnClick(title);

            return false;
        }
    });

    mapView.onResume();

    showMarkers();

    ZoomAsync zoomAsync = new ZoomAsync();
    zoomAsync.execute();
}

Para exibir a janela de informações, recupere o modelo de dados original do mapa do marcador:

@Override
public void onMapReady(GoogleMap googleMap) {
    this.googleMap = googleMap;
    googleMap.setOnInfoWindowClickListener(new GoogleMap.OnInfoWindowClickListener() {
        @Override
        public void onInfoWindowClick(Marker marker) {
            Map dataModel = (Map)markers.get(marker);
            String title = (String)dataModel.get("title");

            infoWindowOnClick(title);
        }
    });
Gary Davies
fonte
Quais são os inconvenientes da implementação do OnMarkerClickListener?
D.Rosado
@ D.Rosado OnMarkerClickListener é para quando o marcador é clicado, OnInfoWindowClickListener é para quando a janela de informações é clicada. Estou entendendo mal sua pergunta? Implemente cada linha para manter a implementação dentro do mesmo código que o setter.
Gary Davies
3

Outra solução: você recebe o marcador pelo título

public class MarkerDemoActivity extends android.support.v4.app.FragmentActivity implements OnMarkerClickListener
{
      private Marker myMarker;    

      private void setUpMap()
      {
      .......
      googleMap.setOnMarkerClickListener(this);

      myMarker = googleMap.addMarker(new MarkerOptions()
                  .position(latLng)
                  .title("My Spot")
                  .snippet("This is my spot!")
                  .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE)));
      ......
      }

  @Override
  public boolean onMarkerClick(final Marker marker) 
  {

     String name= marker.getTitle();

      if (name.equalsIgnoreCase("My Spot")) 
      {
          //write your code here
      }
  }
}
Osama Ibrahim
fonte
2

Aqui está meu código inteiro de uma atividade de mapa com 4 marcadores clicáveis. Clicar em um marcador mostra uma janela de informações e, depois de clicar na janela de informações, você vai para outra atividade: inglês, alemão, espanhol ou italiano. Se você deseja usar o OnMarkerClickListener, apesar do OnInfoWindowClickListener, basta trocar esta linha:

mMap.setOnInfoWindowClickListener(new GoogleMap.OnInfoWindowClickListener()

para isso:

mMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener()

está linha:

public void onInfoWindowClick(Marker arg0)

para isso:

public boolean onMarkerClick(Marker arg0)

e no final do método "onMarkerClick":

return true;

Eu acho que pode ser útil para alguém;)

package pl.pollub.translator;

import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.widget.Toast;

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {

    private GoogleMap mMap;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_maps);

        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);
        Toast.makeText(this, "Choose a language.", Toast.LENGTH_LONG).show();
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;
        mMap.setOnInfoWindowClickListener(new GoogleMap.OnInfoWindowClickListener()
        {

            @Override
            public void onInfoWindowClick(Marker arg0) {
                if(arg0 != null && arg0.getTitle().equals("English")){
                Intent intent1 = new Intent(MapsActivity.this, English.class);
                startActivity(intent1);}

                if(arg0 != null && arg0.getTitle().equals("German")){
                Intent intent2 = new Intent(MapsActivity.this, German.class);
                startActivity(intent2);} 

                if(arg0 != null && arg0.getTitle().equals("Italian")){
                Intent intent3 = new Intent(MapsActivity.this, Italian.class);
                startActivity(intent3);}

                if(arg0 != null && arg0.getTitle().equals("Spanish")){
                Intent intent4 = new Intent(MapsActivity.this, Spanish.class);
                startActivity(intent4);}
            }
        });
        LatLng greatBritain = new LatLng(51.30, -0.07);
        LatLng germany = new LatLng(52.3107, 13.2430);
        LatLng italy = new LatLng(41.53, 12.29);
        LatLng spain = new LatLng(40.25, -3.41);
        mMap.addMarker(new MarkerOptions()
                .position(greatBritain)
                .title("English")
                .snippet("Click on me:)"));
        mMap.addMarker(new MarkerOptions()
                .position(germany)
                .title("German")
                .snippet("Click on me:)"));
        mMap.addMarker(new MarkerOptions()
                .position(italy)
                .title("Italian")
                .snippet("Click on me:)"));
        mMap.addMarker(new MarkerOptions()
                .position(spain)
                .title("Spanish")
                .snippet("Click on me:)"));
        mMap.moveCamera(CameraUpdateFactory.newLatLng(greatBritain));
        mMap.moveCamera(CameraUpdateFactory.newLatLng(germany));
        mMap.moveCamera(CameraUpdateFactory.newLatLng(italy));
        mMap.moveCamera(CameraUpdateFactory.newLatLng(spain));
    }
}
Pysia93
fonte
1
return true se o ouvinte consumiu o evento (ou seja, o comportamento padrão não deve ocorrer); false caso contrário (ou seja, o comportamento padrão deve ocorrer). O comportamento padrão é que a câmera se mova para o marcador e uma janela de informações apareça.
Ariq 4/18
1
Step 1
public class TopAttractions extends Fragment implements OnMapReadyCallback, 
GoogleMap.OnMarkerClickListener

Step 2
gMap.setOnMarkerClickListener(this);

Step 3
@Override
public boolean onMarkerClick(Marker marker) {
    if(marker.getTitle().equals("sharm el-shek"))
        Toast.makeText(getActivity().getApplicationContext(), "Hamdy", Toast.LENGTH_SHORT).show();
    return false;
}
Hamdy Abd El Fattah
fonte
0

Eu adicionei um mMap.setOnMarkerClickListener(this);no onMapReady(GoogleMap googleMap)método Portanto, toda vez que você clica em um marcador, ele exibe o nome do texto no método brinde.

public class DemoMapActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener,OnMapReadyCallback, GoogleMap.OnMarkerClickListener {

private GoogleMap mMap;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_places);
    Toolbar toolbar = findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
    mapFragment.getMapAsync(this);
}

@Override
public void onMapReady(GoogleMap googleMap) {
    mMap = googleMap;
    double lat=0.34924212701428;
    double lng=32.616554024713;
    String venue = "Capital Shoppers City";
    LatLng location = new LatLng(lat, lng);
    mMap.addMarker(new MarkerOptions().position(location).title(venue)).setTag(0);
    CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLng(location);
    CameraUpdate zoom = CameraUpdateFactory.zoomTo(16);
    mMap.moveCamera(cameraUpdate);
    mMap.animateCamera(zoom);
    mMap.setOnMarkerClickListener(this);
}

@Override
public boolean onMarkerClick(final Marker marker) {
    // Retrieve the data from the marker.
    Integer clickCount = (Integer) marker.getTag();

    // Check if a click count was set, then display the click count.
    if (clickCount != null) {
        clickCount = clickCount + 1;
        marker.setTag(clickCount);
        Toast.makeText(this,
                       marker.getTitle() +
                       " has been clicked ",
                       Toast.LENGTH_SHORT).show();
    }
    // Return false to indicate that we have not consumed the event and that we wish
    // for the default behavior to occur (which is for the camera to move such that the
    // marker is centered and for the marker's info window to open, if it has one).
    return false;
}

}

Você pode verificar este link para obter marcadores de referência

Nelson Katale
fonte
-4

Eu editei o exemplo acima ...

public class YourActivity extends implements OnMarkerClickListener
{
    ......

    private void setMarker()
    {
        .......
        googleMap.setOnMarkerClickListener(this);

        myMarker = googleMap.addMarker(new MarkerOptions()
                    .position(latLng)
                    .title("My Spot")
                    .snippet("This is my spot!")
                    .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE)));
        ......
    }

    @Override
    public boolean onMarkerClick(Marker marker) {

       Toast.makeText(this,marker.getTitle(),Toast.LENGTH_LONG).show();
    }
}
Abdul Rizwan
fonte