带有两个可点击按钮或 ImageView 的 Google 地图 v2 自定义信息窗口

Posted

技术标签:

【中文标题】带有两个可点击按钮或 ImageView 的 Google 地图 v2 自定义信息窗口【英文标题】:Google map v2 Custom Infowindow with two clickable buttons or ImageView 【发布时间】:2013-09-05 05:29:39 【问题描述】:

我需要带有两个可单击按钮的自定义信息窗口,如上所述。在其中,当超过标记并单击其中任何一个时,窗口应该打开,当单击另一个标记时,另一个窗口也应该打开和关闭前一个窗口以及单个点击。 google map v2 不支持按钮、复选框等实时组件有什么具体原因吗?

【问题讨论】:

使用适配器使用自定义弹出窗口,map.setInfoWindowAdapter(new PopupAdapterTodays(getLayoutInflater(bundle), context)); 是的,这是正确的,但我怎样才能获得两种不同的操作,例如在 infowindow 中的第一个按钮上显示 firstactivity 和在第二个按钮上显示 secondactivity。 您可以在适配器中创建自定义布局,您可以有两个带有监听器的按钮 你能建议什么应该公开查看 getInfoWindow() check this 我打开了一个关于点击标记的对话框。 【参考方案1】:

你想要达到的目标是可能的。

你可以在这个答案中看到配方:https://***.com/a/15040761/2183804

还有一个在 Google Play 上的工作实现。

【讨论】:

【参考方案2】:

MainActivity.java

@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public class MainActivity extends Activity 

  private ViewGroup infoWindow;
  private TextView infoTitle;
  private TextView infoSnippet;
  private Button infoButton1, infoButton2;
  private OnInfoWindowElemTouchListener infoButtonListener;

  @Override
  protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.mapwrapperlauot);

    final MapFragment mapFragment =
        (MapFragment) getFragmentManager().findFragmentById(R.id.map);
    final MapWrapperLayout mapWrapperLayout =
        (MapWrapperLayout) findViewById(R.id.map_relative_layout);
    final GoogleMap map = mapFragment.getMap();


    mapWrapperLayout.init(map, getPixelsFromDp(this, 39 + 20));

    final Marker ki = map.addMarker(new MarkerOptions()
        .position(new LatLng(50.08, 14.43))
        .icon(BitmapDescriptorFactory
            .fromResource(R.drawable.circles)));

    infoWindow = (ViewGroup) getLayoutInflater()
        .inflate(R.layout.activity_main, null);
    infoButton1 = (Button) infoWindow.findViewById(R.id.b1);
    infoButton2 = (Button) infoWindow.findViewById(R.id.b2);

    infoButtonListener = new OnInfoWindowElemTouchListener(infoButton1,
        getResources().getDrawable(R.drawable.ic_launcher),
        getResources().getDrawable(R.drawable.ic_launcher)) 
      @Override
      protected void onClickConfirmed(View v, Marker marker) 
        Toast.makeText(getApplicationContext(),
            "click on button 1", Toast.LENGTH_LONG).show();
      
    ;
    infoButton1.setOnTouchListener(infoButtonListener);


    infoButtonListener = new OnInfoWindowElemTouchListener(infoButton2,
        getResources().getDrawable(R.drawable.ic_launcher),
        getResources().getDrawable(R.drawable.ic_launcher)) 
      @Override
      protected void onClickConfirmed(View v, Marker marker) 
        Toast.makeText(getApplicationContext(),
            "click on button 2", Toast.LENGTH_LONG).show();
      
    ;
    infoButton2.setOnTouchListener(infoButtonListener);

    infoWindow.setOnClickListener(new OnClickListener() 
      @Override
      public void onClick(View v) 
        // TODO Auto-generated method stub
      
    );

    map.setInfoWindowAdapter(new InfoWindowAdapter() 
      @Override
      public View getInfoWindow(Marker marker) 
        infoButtonListener.setMarker(marker);
        mapWrapperLayout.setMarkerWithInfoWindow(marker, infoWindow);
        return infoWindow;
      

      @Override
      public View getInfoContents(Marker marker) 
        // Setting up the infoWindow with current's marker info
        return null;
      
    );
    ki.showInfoWindow();

    map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(50.08, 14.43), 15));
    map.animateCamera(CameraUpdateFactory.zoomTo(10), 2000, null);
  

  public static int getPixelsFromDp(Context context, float dp) 
    final float scale = context.getResources().getDisplayMetrics().density;
    return (int) (dp * scale + 0.5f);
  

activity_main

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_
    android:layout_
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <LinearLayout
        android:layout_
        android:layout_
        android:background="@drawable/marker" >

        <Button 
            android:id="@+id/b1"
            android:layout_
            android:layout_
            android:text="Button1" 
            android:layout_marginBottom="10dp"   />

        <Button 
            android:id="@+id/b2"
            android:layout_
            android:layout_
            android:text="Button2"
            android:layout_marginBottom="10dp"    />

    </LinearLayout>
</RelativeLayout>

现在从链接https://***.com/a/15040761/2183804复制以下文件

    mapwrapperlauot(在标签中包含你的包名) MapWrapperLayout.java OnInfoWindowElemTouchListener.java

它会起作用的。

【讨论】:

我相信您需要为每个按钮制作OnInfoWindowElemTouchListener。您的代码可能毫无例外地工作,因为您只显示一个与特定标记无关的 toast 弹出窗口。如果您在单击infoButton1 时尝试显示标记的标题,您将得到nullpointerexception【参考方案3】:

我已经为这个问题构建了一个示例 android studio 项目。

输出屏幕截图:-

点击下载完整项目源代码 here

请注意:您必须在 Androidmanifest.xml 中添加您的 API 密钥

【讨论】:

【参考方案4】:

你想要达到的目标是不可能的。即使您为信息窗口创建了 XML 布局,信息窗口的内容也会被渲染并以图像的形式呈现在地图上。所以它只能接受整个窗口的一个点击监听器。不能为一个窗口指定多个点击监听器。

更新: 来自Docs:

注意:绘制的信息窗口不是实时视图。视图在返回时呈现为图像(使用 View.draw(Canvas))。这意味着对视图的任何后续更改都不会反映在地图上的信息窗口中。要稍后更新信息窗口(例如,加载图像后),请调用 showInfoWindow()。此外,信息窗口不会尊重任何普通视图的典型交互性,例如触摸或手势事件。但是,您可以在整个信息窗口上收听通用点击事件,如下节所述。

【讨论】:

在谷歌地图 api v1 中我已经使用了自定义叠加层,但在 v2 中这是不可能的 您可以从文档中重新编辑,您尝试做的事情对于 V2 是不可能的【参考方案5】:

实际上有一个库可以解决您的问题并添加一个实时视图的信息窗口,您可以与之交互。

https://github.com/Appolica/InteractiveInfoWindowAndroid

【讨论】:

以上是关于带有两个可点击按钮或 ImageView 的 Google 地图 v2 自定义信息窗口的主要内容,如果未能解决你的问题,请参考以下文章

底部带有相机按钮的 ImageView

android 自定义控件(带有删除按钮的imageview) 怎么在ImageView背景上添加button按钮 动态添加imageview 自带删除图标的imageview list删除某

android中ImageView放大和缩小相关问题?

包含带有很多按钮的 ImageView 的 ScrollView

如何在 Swift 3 中保存带有顶部图像的相机照片

自定义分组表或按钮?