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

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

【问题讨论】:

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

标签: android google-maps custom-controls google-play-services


【解决方案1】:

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

你可以在这个答案中看到配方:https://stackoverflow.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_width="match_parent"
        android:layout_height="match_parent"
        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_height="wrap_content"
            android:layout_width="wrap_content"
            android:background="@drawable/marker" >
    
            <Button 
                android:id="@+id/b1"
                android:layout_height="wrap_content"
                android:layout_width="wrap_content"
                android:text="Button1" 
                android:layout_marginBottom="10dp"   />
    
            <Button 
                android:id="@+id/b2"
                android:layout_height="wrap_content"
                android:layout_width="wrap_content"
                android:text="Button2"
                android:layout_marginBottom="10dp"    />
    
        </LinearLayout>
    </RelativeLayout>
    

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

    1. mapwrapperlauot(在标签中包含你的包名)
    2. MapWrapperLayout.java
    3. 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

      【讨论】:

        猜你喜欢
        • 2013-01-09
        • 1970-01-01
        • 2014-11-13
        • 2014-02-02
        • 2013-02-11
        • 2018-04-03
        • 2013-01-06
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多