Google Maps API v2:如何使标记可点击?

Posted

技术标签:

【中文标题】Google Maps API v2:如何使标记可点击?【英文标题】:Google Maps API v2: How to make markers clickable? 【发布时间】:2012-12-22 23:35:18 【问题描述】:

如何使 android Google Maps API v2 中的标记变为可点击状态,以便它们显示带有选项的菜单或开始新的活动?我相信我目前在我的应用程序中使用“newb”方法制作了标记。我没有为它们分配名称或方法,以便能够将其与所需的其余代码链接。

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

如果您回答了这个问题,请附上一个标记的示例代码,该标记被引入一个唯一的名称,然后被设置为可点击以打开一个新活动。

【问题讨论】:

这里是官方手册:developers.google.com/maps/documentation/android-sdk/… 【参考方案1】:

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
        
    

这是一个很好的guide on google about marker customization

【讨论】:

有没有办法监听弹出窗口的点击?显示您的标题/sn-p 的那个? 与标记相同 - 您需要注册OnInfoWindowClickListenerCallback。 GoogleMap 中有一个方法:googleMap.setOnInfoWindowClickListener(listener); 现在一切都很好,我注意到我的错误是没有在代码的前面将它设置为变量。我只是忘记了“;”以及实现的代码 @JDOaktown 如果你对不同的标记有不同的逻辑,你需要这个检查。假设您只想在单击特定标记时显示祝酒词。如果您对所有标记都有相同的处理逻辑 - 您不需要检查标记 如文档 (developers.google.com/android/reference/com/google/android/gms/…) 中所述,如果点击被消费,您需要返回 true。如果您返回 false - 将发生默认行为【参考方案2】:

setTag(position) 同时向地图添加标记。

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

getTag() setOnMarkerClickListener 监听器

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

【讨论】:

【参考方案3】:

避免使用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 OnMarkerClickListener 用于单击标记时, OnInfoWindowClickListener 用于单击信息窗口时。我误解了你的问题吗?实现每个内联以将实现保持在与 setter 相同的代码中。【参考方案4】:

另一种解决方案:您可以通过标题获取标记

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
      
  

【讨论】:

【参考方案5】:

这是我的带有 4 个可点击标记的地图活动的完整代码。单击标记会显示信息窗口,单击信息窗口后,您将进入另一个活动:英语、德语、西班牙语或意大利语。如果你想在 OnInfoWindowClickListener 的情况下使用 OnMarkerClickListener,你只需要交换这一行:

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

【讨论】:

如果侦听器已经消费了事件,则返回 true(即不应发生默认行为);否则为 false (即,应该发生默认行为)。默认行为是让相机移动到标记处并显示一个信息窗口。【参考方案6】:
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;

【讨论】:

【参考方案7】:

以下 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
        

【讨论】:

【参考方案8】:

Kotlin - 关闭标记点击次数

我对关闭地图上标记的可点击功能的回答。

我在搜索“android map marker close clickable”时发现了这个问题

map.setOnMarkerClickListener  true 

【讨论】:

【参考方案9】:

我在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;

您可以查看此链接以供参考 Markers

【讨论】:

【参考方案10】:

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

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

【讨论】:

以上是关于Google Maps API v2:如何使标记可点击?的主要内容,如果未能解决你的问题,请参考以下文章

在 Google Maps API v2 中更改标记大小

Google android maps api v2 始终显示标记标题

Google Maps Android API v2,错误的标记位置

居中位图标记(Google Maps Android API v2)

如何使用 Google MAps API v2 围绕引脚绘制圆圈

添加大量标记时,Google Maps Android API v2 非常慢