API di Google Maps v2: come rendere selezionabili i marker?


128

Come posso rendere selezionabili i marcatori nell'API di Google Maps per Android v2 in modo da far apparire un menu con le opzioni o semplicemente iniziare una nuova attività? Credo di aver creato i marcatori nella mia app attualmente con un metodo "newb". Non ho assegnato loro un nome o un metodo per poterlo collegare al resto del codice richiesto.

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

Se RISPONDI, includi un codice di esempio di un marcatore che viene introdotto con un nome univoco e quindi impostato come cliccabile per aprire una nuova attività.

Risposte:


238

Tutti gli indicatori in Google Android Maps Api v2 sono selezionabili. Non è necessario impostare ulteriori proprietà sul marker. Quello che devi fare è registrare il callback del click marker sul tuo googleMap e gestire il click nel callback:

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

ecco una buona guida su google sulla personalizzazione dei marker


9
C'è un modo per ascoltare i clic nella finestra popup? Quello che mostra il tuo titolo / snippet?

40
la stessa cosa dei marker: devi registrarti OnInfoWindowClickListenerCallback. Esiste un metodo in GoogleMap per questo:googleMap.setOnInfoWindowClickListener(listener);
Pavel Dudka,

Per ora funziona tutto molto bene, ho notato che il mio errore non era quello di impostarlo come variabile prima nel codice. Ho semplicemente dimenticato il ";" e il codice implementato
Malaka,

1
@JDOaktown hai bisogno di questo controllo se hai una logica diversa per marcatori diversi. Diciamo che vuoi mostrare un brindisi solo quando si fa clic su un marker specifico. Se hai la stessa logica di gestione per tutti i tuoi marcatori - non è necessario controllarli
Pavel Dudka,

1
Come indicato nella documentazione ( developers.google.com/android/reference/com/google/android/gms/… ), è necessario restituire true se il clic è stato consumato. Se restituisci false, si verificherà un comportamento predefinito
Pavel Dudka,

36

setTag(position) mentre aggiungi un marker alla mappa.

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

getTag()su setOnMarkerClickListenerchi ascolta

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

4

Evita di usare gli strumenti di attività OnMarkerClickListener, usa un OnMarkerClickListener locale

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

Avrai bisogno di una mappa per cercare il modello di dati originale collegato al marcatore

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

Avrai bisogno di un modello di dati

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

Inserisci alcuni dati nel modello dati

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

Quando si crea un nuovo marcatore utilizzando un modello di dati, aggiungere entrambi alla mappa del creatore

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

Per l'evento marcatore on click, usa un OnMarkerClickListener locale:

@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();
}

Per visualizzare la finestra informativa, recuperare il modello di dati originale dalla mappa marcatore:

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

Quali sono gli svantaggi dell'implementazione di OnMarkerClickListener?
D.Rosado,

@ D.Rosado OnMarkerClickListener è per quando si fa clic sul marcatore, OnInfoWindowClickListener è quando si fa clic sulla finestra informativa. Sto fraintendendo la tua domanda? Implementare ogni inline per mantenere l'implementazione all'interno dello stesso codice del setter.
Gary Davies,

3

Un'altra soluzione: ottieni il marker dal suo titolo

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

2

Ecco il mio intero codice di un'attività sulla mappa con 4 marcatori cliccabili. Fare clic su un indicatore mostra una finestra informativa e dopo aver fatto clic sulla finestra informativa, si passa a un'altra attività: inglese, tedesco, spagnolo o italiano. Se vuoi usare OnMarkerClickListener nonostante OnInfoWindowClickListener, devi solo scambiare questa linea:

mMap.setOnInfoWindowClickListener(new GoogleMap.OnInfoWindowClickListener()

a questa:

mMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener()

questa linea:

public void onInfoWindowClick(Marker arg0)

a questa:

public boolean onMarkerClick(Marker arg0)

e alla fine del metodo "onMarkerClick":

return true;

Penso che possa essere utile per qualcuno;)

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

1
restituisce true se il listener ha consumato l'evento (ovvero, il comportamento predefinito non dovrebbe verificarsi); false altrimenti (ovvero, dovrebbe verificarsi il comportamento predefinito). Il comportamento predefinito prevede che la telecamera si sposti sul marker e appaia una finestra informativa.
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;
}

0

Ho aggiunto a mMap.setOnMarkerClickListener(this);nel onMapReady(GoogleMap googleMap)metodo. Quindi ogni volta che si fa clic su un marcatore, viene visualizzato il nome del testo nel metodo toast.

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

}

È possibile controllare questo collegamento per i marker di riferimento


-4

Ho modificato l'esempio sopra riportato ...

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();
    }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.