OsmDroid bonus pack: Markers with clickable InfoWindows

After finding the useful Tutorial_1 to quickly implement InfoWindows (these bubbles over the Markers that provide additional info), i’ve extended it to easily override the onClick behaviour.

Step 1: Adding an id to the bonuspack_bubble’s root Layout

Inside res/layout, edit the files “bonuspack_bubble.xml” and “bonuspack_bubble_black.xml”

Insert this line on line 3:

android:id="@+id/bubble_layout"

So the root LinearLayout element remains like this in both files:

<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:id="@+id/bubble_layout"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content" 
 android:orientation="horizontal"
 android:background="@drawable/bonuspack_bubble_black" >
... rest of the file remains the same
</LinearLayout>

Now, in your Main Activity, create this private class:

private class MyInfoWindow extends InfoWindow{
   public MyInfoWindow(int layoutResId, MapView mapView) {
      super(layoutResId, mapView); 
   }
   public void onClose() {
   }

   public void onOpen(Object arg0) {
      LinearLayout layout = (LinearLayout) mView.findViewById(R.id.bubble_layout);
      Button btnMoreInfo = (Button) mView.findViewById(R.id.bubble_moreinfo); 
      TextView txtTitle = (TextView) mView.findViewById(R.id.bubble_title);
      TextView txtDescription = (TextView) mView.findViewById(R.id.bubble_description);
      TextView txtSubdescription = (TextView) mView.findViewById(R.id.bubble_subdescription);

      txtTitle.setText("Title of my marker");
      txtDescription.setText("Click here to view details!");
      txtSubdescription.setText("You can also edit the subdescription");
      layout.setOnClickListener(new OnClickListener() {
         public void onClick(View v) {
            // Override Marker's onClick behaviour here
         }
      }); 
   } 
}

Now add one of those MyInfoWindow to each Marker like this:

Marker startMarker = new Marker(mMapView);
startMarker.setPosition(new GeoPoint(mLat,mLon));
startMarker.setIcon(R.drawable.ic_launcher); 
startMarker.setAnchor(Marker.ANCHOR_CENTER, 1.0f);
InfoWindow infoWindow = new MyInfoWindow(R.layout.bonuspack_bubble, mMapView);
startMarker.setInfoWindow(infoWindow);
mMapView.getOverlays().add(startMarker);
startMarker.setTitle("Title of the marker");

Try it and see how it goes.

As you have noticed, i’m not using the “More info” button inside the bubble.

Instead, i’m overriding the onClick of the whole bubble, because i find it more intuitive. If you want to use the “More info” button, then:

btnMoreInfo.setVisibility(Button.VISIBLE);
 btnMoreInfo.setOnClickListener(new OnClickListener() {
   public void onClick(View v) {
      // Implement onClick behaviour
   }
 });

Give it a try and see how it goes! feel free to post any feedback or suggestions.

10 thoughts on “OsmDroid bonus pack: Markers with clickable InfoWindows

  1. Great idea and implementation.
    In my case, layout.setOnClickListener->onClick is never called. However, with the button.onClick it works.
    I’m using the osmbonuspack_v4.5 and osmdroid_v4.2.
    It seems that I’ll have to add additional logic in the MyInfoWindow.onClose

    Thank you for a nice workaround.

    • Thanks 🙂 probably would be a good idea to have a common OnClickListener for both (button and layout). In the devices i tested it seems to work fine, but maybe you are right and sometimes the onClick event is not fired.

      • I made a mistake.
        First, I don’t have
        android:background=”@drawable/bonuspack_bubble_black”
        in my bonuspack_bubble.xml (and I skipped the first step you explained).
        Anyways, I made it work by setting id and onClick handler on the second LinearLayout in bonuspack_bubble.xml.

    • you can make it disappear manually. try this inside the InfoWindow’s onOpen() method

      for(int i=0; i<mMapView.getOverlays().size(); ++i){
      Overlay o = mMapView.getOverlays().get(i);
      if(o instanceof Marker){
      Marker m = (Marker) o;
      Marker current = (Marker) arg0;
      if(!m.getTitle().equals(current.getTitle()))
      m.hideInfoWindow();
      }
      }

  2. does not work if(!m.getTitle().equals(current.getTitle())) ..

    I do so
    Marker current = (Marker) arg0;
    for(int i=0; i<mMapView.getOverlays().size(); ++i){
    Overlay o = mMapView.getOverlays().get(i);

    if(o instanceof Marker){
    Marker m = (Marker) o;
    if(m!=current)
    m.hideInfoWindow();
    }

    }

    thanks!!!

Leave a reply to mobiledevstories Cancel reply