【问题标题】:Google Maps API v2: How to make markers clickable?Google Maps API v2:如何使标记可点击?
【发布时间】: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)));

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

【问题讨论】:

标签: android google-maps google-maps-android-api-2


【解决方案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();
                  }
              }
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2013-05-28
                • 2012-08-27
                • 2013-08-31
                • 2012-03-24
                • 1970-01-01
                • 2019-01-31
                相关资源
                最近更新 更多