谷歌地图API v2:如何使标记可点击?

142

我该如何使Android Google Maps API v2中的标记可点击,以便它们可以弹出带有选项菜单或启动新活动的菜单?我认为我在应用程序中的标记目前是使用“新手”方法创建的。我没有给它们分配名称或方法,以便能够将其与其他必需代码链接起来。

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

如果您要回答这个问题,请包含一个引入具有唯一名称的标记并将其设置为可点击以打开新活动的示例代码。


这是官方手册链接:https://developers.google.com/maps/documentation/android-sdk/marker#associate_data_with_a_marker - Liker777
10个回答

252

Google Android Maps Api v2中的所有标记都是可点击的。您无需为标记设置任何其他属性。

您需要做的是将标记单击回调函数注册到您的googleMap,并在回调函数中处理单击:

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

这里有一篇谷歌关于标记定制的好指南


11
有没有一种方法可以监听弹出窗口上的点击事件?这个弹出窗口会显示您的标题/摘要。 - user901309
42
与标记器的情况类似-您需要注册OnInfoWindowClickListenerCallback。 GoogleMap 中有一个方法可以做到这一点:googleMap.setOnInfoWindowClickListener(listener); - Pavel Dudka
我如何为每个被点击的标记添加自定义布局? - IgorGanapolsky
1
@JDOaktown,如果您对不同的标记有不同的逻辑,请使用此检查。假设您只想在单击特定标记时显示一个toast。如果您对所有标记具有相同的处理逻辑-则无需检查标记。 - Pavel Dudka
2
如文档所述(https://developers.google.com/android/reference/com/google/android/gms/maps/GoogleMap.OnMarkerClickListener),如果点击被消耗,您需要返回true。如果您返回false,则会发生默认行为。 - Pavel Dudka
显示剩余3条评论

51

setTag(position) 在向地图添加标记时使用。

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

setOnMarkerClickListener监听器中的getTag()

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

6
避免使用Activity实现OnMarkerClickListener,使用本地的OnMarkerClickListener。
// Not a good idea
class MapActivity extends Activity implements OnMarkerClickListener {
}

您需要一张地图来查找链接到标记的原始数据模型。

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

您需要一个数据模型

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

在数据模型中添加一些数据

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

使用数据模型创建新标记时,请将两者都添加到标记地图中。
Marker marker = googleMap.addMarker(markerOptions);
markers.put(marker, dataModel);

对于点击标记事件,请使用本地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();
}

要显示信息窗口,请从标记映射中检索原始数据模型:

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

实现OnMarkerClickListener有哪些缺点? - D.Rosado
@D.Rosado OnMarkerClickListener 是当标记被点击时使用的,OnInfoWindowClickListener 是当信息窗口被点击时使用的。我是否误解了你的问题?将每个内联实现以使实现保持在与设置器相同的代码中。 - Gary Davies

3
另一种解决方案:通过标记的标题获取标记。
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
      }
  }
}

3

以下 Kotlin 代码可以帮助你

创建标记

        for (i in arrayList.indices) {
            val marker = googleMap!!.addMarker(
                MarkerOptions().position(
                    LatLng(
                        arrayList[i].location_latitude!!.toDoubleOrNull()!!,
                        arrayList[i].location_latitude!!.toDoubleOrNull()!!
                    )
                ).title(arrayList[i].business_name)
                    .icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_marker))
            )
            marker.tag = i
        }

标记点击

        googleMap!!.setOnMarkerClickListener { marker ->
            Log.d(TAG, "Clicked on  ${marker.tag}")
            true
        }

3
这是一个带有四个可点击标记的地图活动的完整代码。点击标记会显示信息窗口,然后再次点击信息窗口会进入另一个活动:英语,德语,西班牙语或意大利语。如果你想使用OnMarkerClickListener而不是OnInfoWindowClickListener,只需要交换这一行代码:
mMap.setOnInfoWindowClickListener(new GoogleMap.OnInfoWindowClickListener()

转换为:

mMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener()

这行文字:
public void onInfoWindowClick(Marker arg0)

转换为:

public boolean onMarkerClick(Marker arg0)

在“onMarkerClick”方法的末尾:
return true;

我认为这可能对某些人有帮助 ;)

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
如果监听器消耗了事件(即默认行为不应发生),则返回true;否则返回false(即默认行为应发生)。默认行为是相机移动到标记并出现信息窗口。 - Ariq

1

Kotlin - 关闭地图标记的可点击功能

以下是关闭地图标记可点击功能的解决方案。

当我搜索“android地图标记关闭可点击”时,发现了这个问题。

map.setOnMarkerClickListener { true }

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
我在 onMapReady(GoogleMap googleMap) 方法中添加了 mMap.setOnMarkerClickListener(this);。因此,每次单击标记时,它都会在 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;
}

}

您可以查看此链接以供参考标记


-4

我已经编辑了上面给出的例子...

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接