API Google Maps v2: comment rendre les marqueurs cliquables?

128

Comment faire en sorte que les marqueurs de l'API Google Maps v2 d'Android deviennent cliquables pour qu'ils affichent un menu avec des options ou démarrent simplement une nouvelle activité? Je crois que j'ai fait les marqueurs dans mon application actuellement dans une méthode "newb". Je ne leur ai pas attribué de nom ou de méthode pour pouvoir le lier avec le reste du code requis.

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

Si vous RÉPONDEZ à cela, veuillez inclure un exemple de code d'un marqueur introduit avec un nom unique puis défini comme cliquable pour ouvrir une nouvelle activité.

Malaka
la source

Réponses:

238

Tous les marqueurs dans Google Android Maps Api v2 sont cliquables. Vous n'avez pas besoin de définir de propriétés supplémentaires pour votre marqueur. Ce que vous devez faire, c'est enregistrer le rappel de clic de marqueur dans votre googleMap et gérer le clic dans le rappel:

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

voici un bon guide sur google sur la personnalisation des marqueurs

Pavel Dudka
la source
9
Existe-t-il un moyen d'écouter les clics sur la fenêtre contextuelle? Celui qui affiche votre titre / extrait?
40
la même chose que pour les marqueurs - vous devez vous inscrire OnInfoWindowClickListenerCallback. Il existe une méthode dans GoogleMap pour cela:googleMap.setOnInfoWindowClickListener(listener);
Pavel Dudka
Tout fonctionne très bien pour le moment, j'ai remarqué que mon erreur n'était pas de le définir comme variable plus tôt dans le code. J'ai simplement oublié le ";" et le code implémenté
Malaka
1
@JDOaktown vous avez besoin de cette vérification si vous avez une logique différente pour différents marqueurs. Disons que vous souhaitez afficher un toast uniquement lorsqu'un marqueur spécifique est cliqué. Si vous avez la même logique de manipulation pour tous vos marqueurs - vous n'avez pas besoin de vérifier le marqueur
Pavel Dudka
1
Comme mentionné dans la documentation ( développeurs.google.com /android/reference/com/google/android/gms/…), vous devez renvoyer true si le clic a été utilisé. Si vous retournez false - le comportement par défaut se produira
Pavel Dudka
36

setTag(position) tout en ajoutant un marqueur à la carte.

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

getTag()sur l' setOnMarkerClickListenerauditeur

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
la source
4

Évitez d'utiliser des implémentations d'activité OnMarkerClickListener, utilisez un OnMarkerClickListener local

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

Vous aurez besoin d'une carte pour rechercher le modèle de données d'origine lié au marqueur

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

Vous aurez besoin d'un modèle de données

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

Mettez des données dans le modèle de données

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

Lors de la création d'un nouveau marqueur à l'aide d'un modèle de données, ajoutez les deux à la carte Maker

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

Pour un événement de marqueur de clic, utilisez 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();
}

Pour afficher la fenêtre d'informations, récupérez le modèle de données d'origine à partir de la carte des marqueurs:

@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
la source
Quels sont les inconvénients de l'implémentation d'OnMarkerClickListener?
D.Rosado
@ D.Rosado OnMarkerClickListener est pour lorsque le marqueur est cliqué, OnInfoWindowClickListener est lorsque la fenêtre d'informations est cliquée. Suis-je mal compris votre question? Implémentez chaque inline pour conserver l'implémentation dans le même code que le setter.
Gary Davies
3

Une autre solution: vous obtenez le marqueur par son titre

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
      }
  }
}
Oussama Ibrahim
la source
2

Voici mon code complet d'une activité cartographique avec 4 marqueurs cliquables. Cliquez sur un marqueur pour afficher une fenêtre d'informations, et après avoir cliqué sur la fenêtre d'informations, vous passez à une autre activité: anglais, allemand, espagnol ou italien. Si vous souhaitez utiliser OnMarkerClickListener malgré OnInfoWindowClickListener, il vous suffit de permuter cette ligne:

mMap.setOnInfoWindowClickListener(new GoogleMap.OnInfoWindowClickListener()

pour ça:

mMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener()

cette ligne:

public void onInfoWindowClick(Marker arg0)

pour ça:

public boolean onMarkerClick(Marker arg0)

et à la fin de la méthode "onMarkerClick":

return true;

Je pense que cela peut être utile pour quelqu'un;)

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
la source
1
renvoie true si l'auditeur a consommé l'événement (c'est-à-dire que le comportement par défaut ne devrait pas se produire); false sinon (c'est-à-dire que le comportement par défaut devrait se produire). Le comportement par défaut est que la caméra se déplace vers le marqueur et qu'une fenêtre d'informations apparaisse.
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
la source
0

J'ai ajouté un mMap.setOnMarkerClickListener(this);dans la onMapReady(GoogleMap googleMap)méthode. Ainsi, chaque fois que vous cliquez sur un marqueur, le nom du texte s'affiche dans la méthode 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;
}

}

Vous pouvez consulter ce lien pour les marqueurs de référence

Nelson Katale
la source
-4

J'ai édité l'exemple ci-dessus ...

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
la source