Google Maps API v2: Jak sprawić, by znaczniki były klikalne?

133

Jak sprawić, by znaczniki w Android Google Maps API v2 stały się klikalne, aby albo wyświetlały menu z opcjami, albo po prostu rozpoczęły nowe działanie? Wydaje mi się, że znaczniki w mojej aplikacji są obecnie tworzone metodą „newb”. Nie przypisałem im nazwy ani metody, aby móc połączyć go z resztą wymaganego kodu.

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

Jeśli ODPOWIEDZ na to, dołącz przykładowy kod wprowadzanego znacznika z unikalną nazwą, a następnie ustawiany jako klikalny, aby otworzyć nowe działanie.

Malaka
źródło

Odpowiedzi:

242

Wszystkie znaczniki w Google Android Maps Api v2 są klikalne. Nie musisz ustawiać żadnych dodatkowych właściwości swojego znacznika. To, co musisz zrobić - to zarejestrować wywołanie zwrotne kliknięcia znacznika w swojej GoogleMap i obsłużyć kliknięcie w ramach wywołania zwrotnego:

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

tutaj jest dobry przewodnik w Google na temat dostosowywania znaczników

Pavel Dudka
źródło
9
Czy istnieje sposób nasłuchiwania kliknięć w wyskakującym okienku? Ten, który wyświetla Twój tytuł / fragment?
40
to samo co ze markerami - musisz się zarejestrować OnInfoWindowClickListenerCallback. W GoogleMap jest na to metoda:googleMap.setOnInfoWindowClickListener(listener);
Pavel Dudka,
Na razie wszystko działa bardzo dobrze, zauważyłem, że mój błąd nie polegał na ustawieniu jej jako zmiennej we wcześniejszej części kodu. Po prostu zapomniałem „;” a zaimplementowany kod
Malaka
1
@JDOaktown potrzebujesz tego sprawdzenia, jeśli masz inną logikę dla różnych znaczników. Powiedzmy, że chcesz pokazać toast tylko po kliknięciu określonego znacznika. Jeśli masz taką samą logikę obsługi dla wszystkich swoich znaczników - nie musisz sprawdzać znacznika
Pavel Dudka
1
Jak wspomniano w dokumentacji ( developers.google.com/android/reference/com/google/android/gms/… ), jeśli kliknięcie zostało wykorzystane, musisz zwrócić wartość „prawda”. Jeśli zwrócisz false - wystąpi domyślne zachowanie
Pavel Dudka
42

setTag(position) podczas dodawania znacznika do mapy.

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

getTag()na setOnMarkerClickListenersłuchacza

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
źródło
5

Unikaj używania implementacji Activity OnMarkerClickListener, użyj lokalnego OnMarkerClickListener

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

Do wyszukania oryginalnego modelu danych połączonego ze znacznikiem będzie potrzebna mapa

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

Będziesz potrzebował modelu danych

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

Umieść dane w modelu danych

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

Tworząc nowy znacznik za pomocą modelu danych, dodaj oba do mapy kreatora

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

W przypadku zdarzenia znacznika kliknięcia użyj lokalnego OnMarkerClickListener:

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

Aby wyświetlić okno informacyjne, pobierz oryginalny model danych z mapy znaczników:

@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
źródło
Jakie są wady implementacji OnMarkerClickListener?
D.Rosado,
@ D.Rosado OnMarkerClickListener jest używany po kliknięciu znacznika, OnInfoWindowClickListener jest używany po kliknięciu okna informacyjnego. Czy źle zrozumiałem twoje pytanie? Zaimplementuj każdy element wbudowany, aby zachować implementację w tym samym kodzie, co metoda ustawiająca.
Gary Davies,
3

Inne rozwiązanie: otrzymujesz znacznik według jego tytułu

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
źródło
2

Oto mój cały kod aktywności na mapie z 4 klikalnymi znacznikami. Po kliknięciu znacznika pojawi się okno informacyjne, a po kliknięciu w okno informacyjne przejdziesz do innego zadania: angielskiego, niemieckiego, hiszpańskiego lub włoskiego. Jeśli chcesz używać OnMarkerClickListener pomimo OnInfoWindowClickListener, wystarczy zamienić tę linię:

mMap.setOnInfoWindowClickListener(new GoogleMap.OnInfoWindowClickListener()

do tego:

mMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener()

ta linia:

public void onInfoWindowClick(Marker arg0)

do tego:

public boolean onMarkerClick(Marker arg0)

a na końcu metody „onMarkerClick”:

return true;

Myślę, że to może być pomocne dla kogoś;)

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
źródło
1
zwraca prawdę, jeśli detektor wykorzystał zdarzenie (tj. domyślne zachowanie nie powinno wystąpić); fałsz w przeciwnym razie (tj. powinno wystąpić zachowanie domyślne). Domyślnie kamera przesuwa się do znacznika i pojawia się okno informacyjne.
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
źródło
0

Dodałem mMap.setOnMarkerClickListener(this);w onMapReady(GoogleMap googleMap)metodzie. Dlatego za każdym razem, gdy klikniesz znacznik, w metodzie wyrzucania wyświetla nazwę tekstu.

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

}

Możesz sprawdzić ten link, aby znaleźć znaczniki odniesienia

Nelson Katale
źródło
-4

Podany powyżej przykład redagowałem ...

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
źródło