android – Google map v2 Custom Infowindow with two clickable buttons or ImageView-ThrowExceptions

Exception or error:

enter image description here

I need custom info window with two clickable button as above.In it when more then marker and click any one of them then window should be open and when click on another marker another window should open and close previous window as well in single click.
is there any specific reason why google map v2 not support live component like button ,check box?

How to solve:

What you are trying to achieve is possible.

You can see the recipe in this answer: https://stackoverflow.com/a/15040761/2183804

And a working implementation on Google Play.

###

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>

now copy the following files from the link https://stackoverflow.com/a/15040761/2183804

  1. mapwrapperlauot (include your package name in tag)
  2. MapWrapperLayout.java
  3. OnInfoWindowElemTouchListener.java

It will work.

###

I have build a sample android studio project for this question.

output screen shots :-

enter image description here

enter image description here

enter image description here

Download full project source code Click here

Please note: you have to add your API key in Androidmanifest.xml

###

What you are trying to achieve is not possible. Even if you create an XML layout for your info-window, info window contents are rendered and presented as an image on the maps. So it can accept only one click listener for the whole window. You can’t specify multiple click listeners for a window.

UPDATE:
From the Docs:

Note: The info window that is drawn is not a live view. The view is rendered as an image (using View.draw(Canvas)) at the time it is returned. This means that any subsequent changes to the view will not be reflected by the info window on the map. To update the info window later (e.g., after an image has loaded), call showInfoWindow(). Furthermore, the info window will not respect any of the interactivity typical for a normal view such as touch or gesture events. However you can listen to a generic click event on the whole info window as described in the section below.

###

There is actually a library that can resolve your problem and add an info window that is a live view and you can interact with it.

https://github.com/Appolica/InteractiveInfoWindowAndroid

Leave a Reply

Your email address will not be published. Required fields are marked *