Google Maps API v2: ¿Cómo hacer que se pueda hacer clic en los marcadores?

128

¿Cómo hago que los marcadores en Android Google Maps API v2 sean clicables para que aparezcan un menú con opciones o simplemente comiencen una nueva actividad? Creo que hice los marcadores en mi aplicación actualmente en un método "newb". No les asigné un nombre o un método para poder vincularlo con el resto del código requerido.

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

Si RESPONDE esto, incluya un código de muestra de un marcador que se introduce con un nombre único y luego se configura como cliqueable para abrir una nueva actividad.

Malaka
fuente

Respuestas:

238

Se puede hacer clic en todos los marcadores en Google Android Maps Api v2. No necesita establecer ninguna propiedad adicional en su marcador. Lo que debe hacer es registrar la devolución de llamada de clic de marcador en su googleMap y manejar el clic dentro de la devolución de llamada:

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
        }
    }
}

Aquí hay una buena guía en Google sobre la personalización de marcadores

Pavel Dudka
fuente
9
¿Hay alguna forma de escuchar los clics en la ventana emergente? ¿El que muestra tu título / fragmento?
40
lo mismo que con los marcadores: debe registrarse OnInfoWindowClickListenerCallback. Hay un método en GoogleMap para eso:googleMap.setOnInfoWindowClickListener(listener);
Pavel Dudka
Todo funciona muy bien por ahora, noté que mi error no fue establecerlo como una variable anterior en el código. Simplemente olvidé el ";" y el código implementado
Malaka
1
@JDOaktown necesita esta verificación si tiene una lógica diferente para diferentes marcadores. Digamos que desea mostrar un brindis solo cuando se hace clic en un marcador específico. Si tiene la misma lógica de manejo para todos sus marcadores - no necesita verificar el marcador
Pavel Dudka
1
Como se menciona en la documentación ( developers.google.com/android/reference/com/google/android/gms/… ), debe devolver true si se consumió el clic. Si devuelve falso, se producirá un comportamiento predeterminado
Pavel Dudka
36

setTag(position) mientras agrega marcador al mapa.

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

getTag()en el setOnMarkerClickListeneroyente

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
fuente
4

Evite usar los implementos de actividad OnMarkerClickListener, use un OnMarkerClickListener local

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

Necesitará un mapa para buscar el modelo de datos original vinculado al marcador

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

Necesitará un modelo de datos.

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

Poner algunos datos en el modelo de datos

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

Al crear un nuevo marcador con un modelo de datos, agregue ambos al mapa del creador

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

Para el evento de marcador al hacer clic, use un 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 mostrar la ventana de información, recupere el modelo de datos original del mapa de marcadores:

@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
fuente
¿Cuáles son los inconvenientes de implementar OnMarkerClickListener?
D.Rosado
@ D.Rosado OnMarkerClickListener es para cuando se hace clic en el marcador, OnInfoWindowClickListener es cuando se hace clic en la ventana de información. ¿Estoy malinterpretando tu pregunta? Implemente cada línea para mantener la implementación dentro del mismo código que el configurador.
Gary Davies
3

Otra solución: obtienes el marcador por su 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
fuente
2

Aquí está mi código completo de una actividad de mapa con 4 marcadores en los que se puede hacer clic. Hacer clic en un marcador muestra una ventana de información, y después de hacer clic en la ventana de información, pasará a otra actividad: inglés, alemán, español o italiano. Si desea utilizar OnMarkerClickListener a pesar de OnInfoWindowClickListener, solo tiene que cambiar esta línea:

mMap.setOnInfoWindowClickListener(new GoogleMap.OnInfoWindowClickListener()

a esto:

mMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener()

esta línea:

public void onInfoWindowClick(Marker arg0)

a esto:

public boolean onMarkerClick(Marker arg0)

y al final del método "onMarkerClick":

return true;

Creo que puede ser útil para alguien;)

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
fuente
1
devuelve verdadero si el oyente ha consumido el evento (es decir, el comportamiento predeterminado no debería ocurrir); falso de lo contrario (es decir, el comportamiento predeterminado debería ocurrir). El comportamiento predeterminado es que la cámara se mueva al marcador y aparezca una ventana de información.
Ariq
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
fuente
0

Agregué un mMap.setOnMarkerClickListener(this);en el onMapReady(GoogleMap googleMap)método. Por lo tanto, cada vez que hace clic en un marcador, muestra el nombre del texto en el método de brindis.

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;
}

}

Puede consultar este enlace para marcadores de referencia

Nelson Katale
fuente
-4

He editado el ejemplo anterior dado ...

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
fuente