Home > Android, programming, regular > Android – OverlayItem.setMarker(Drawable icon)

Android – OverlayItem.setMarker(Drawable icon)


I’ve been developing in Android for a little over two months off and on and am finding certain things I really love and certain things I hate.  This is one of the things I hate.

Android provides a nice class to manage drawing OverlayItems to a map called ItemizedOverlay; for instance you might want to display all the people in your contact list on a map.  Well, you’d probably want to display a different icon for each person, right?  OK, examine the API.

setMarker

public void setMarker(android.graphics.drawable.Drawable marker)

Sets the marker to be used when drawing this item on the map. Setting the marker to null will cause the default marker to be drawn (the marker is null by default, so you can just skip this, instead). The marker may be drawn using any combination of the null, R.attr.state_pressed, R.attr.state_selected and R.attr.state_focused attributes.

OK, that looks perfect.  Go ahead and give each OverlayItem the Drawable icon you want to use.  Look at the map and… wait a minute.  Nothing shows up.  Why is that?  It works when you haven’t specified the marker…

Well, what this method fails to inform you is that you must define the bounds of a Drawable object before you use it on a map.  The definition of Drawable says

The setBounds(Rect) method must be called to tell the Drawable where it is drawn and how large it should be. All Drawables should respect the requested size, often simply by scaling their imagery. A client can find the preferred size for some Drawables with the getIntrinsicHeight() and getIntrinsicWidth() methods.

So to solve the problem we must do the following:

Drawable icon = getResources().getDrawable(someicon);
icon.setBounds(0, 0, icon.getIntrinsicWidth(), icon.getIntrinsicHeight());
personItem.setMarker(icon);

I wish that an icon defaulted to having its drawable bounds be the rectangle (0, 0, width, height), but you must explicitly define these bounds.

Categories: Android, programming, regular Tags:
  1. Michael S
    February 8, 2010 at 4:55 pm

    I tried your code on a mapview object. However, absolutely nothing displays on the map. My code is:

    public void makemarker(int lat, int lon)
    {
    p = new GeoPoint(lat,lon);
    Projection getcoords;
    Point pcon = new Point(0,0);
    getcoords = mapView.getProjection();
    getcoords.toPixels(p, pcon);

    OverlayItem oi = new OverlayItem(p, mapView.getClass().getName(), “”);

    Drawable icon = getResources().getDrawable(R.drawable.icon);

    icon.setBounds(0, 0, 0 + icon.getIntrinsicWidth(), 0 + icon.getIntrinsicHeight());

    oi.setMarker(icon);
    }

    Any ideas what could be amiss?
    Your help would be much appreciated.

    • February 8, 2010 at 5:11 pm

      You’re missing a step: do this first.

      private ItemizedOverlay itemizedOverlay;
      private List mapOverlays;

      MapView view = …;
      mapOverlays = mapView.getOverlays();

      Drawable drawable = …;
      // Itemized overlay draws all of our people, places, events on map

      // Your subclass implementation of ItemizedOverlay should add an add method
      itemizedOverlay = …;

      mapOverlays.add(itemizedOverlay);

      Later:

      public void makemarker(int lat, int lon)
      {
      // Stuff you have in there

      // Your subclass for itemizedOverlay should expose add functionality to underlying collection or however you store the overlays.
      itemizedOverlay.add(oi);
      }

  2. Santiago
    March 19, 2010 at 7:45 am

    DUDE I LOVE YOU!!
    You saved me many ours of hassle

    • i82much
      March 19, 2010 at 3:20 pm

      Glad this helped. It seems most people find my blog posts when searching for Android problems… maybe I need to do some more Android development and drive some traffic 🙂

  3. Arp
    April 8, 2010 at 5:26 pm

    I’ve been looking for a way to correct this exact problem…thanks so much!

    • Nick
      April 8, 2010 at 7:01 pm

      Glad this helped! I don’t know why Android doesn’t make this more clear.

      Nick

  4. Dongsu
    April 14, 2010 at 3:07 pm

    Thanks a lot. Your articles on android + google map are great!
    Do you know how I might change the color or shade of the marker when it is focused?

    • i82much
      May 9, 2010 at 10:17 am

      Sorry I haven’t looked into this. You’d probably need a separate drawable for the focused state and switch it out when that state occurs

  5. Amol
    May 9, 2010 at 5:48 am

    Thanks a lot for all your efforts; a real time saver. Thanks once again.

  6. cyruscode
    July 17, 2010 at 10:56 am

    Hey Nick! thank you one more time for this tip.. i’ve been wondering like for one week if it was possible afterall to have one overlay with multiple markers…. 😀

  7. i82much
    July 17, 2010 at 11:13 am

    Glad everyone finds this tip useful. I really wish they made it a bit more explicit how you’re supposed to do this stuff.. glad people are stumbling onto the blog.

  8. October 3, 2010 at 10:34 pm

    Ah, *thanks a lot* – I should have started to google 2 hours earlier. Can’t believe setMarker() behaves so stupidly and it’s not even mentioned in the method’s docs. Arghh..

    Thanks 🙂

  9. jhoffman
    November 4, 2010 at 9:16 pm

    GREAT tip! Saved me a ton of wasted effort. Thanks so much!

  10. jd
    November 6, 2010 at 4:15 pm

    Glad I found your explanation…it was very frustrating to have my marker not show up. Thanks!

  11. Biggy
    January 11, 2011 at 1:09 pm

    Thank you very much, you saved me.

    • i82much
      January 11, 2011 at 1:36 pm

      Awesome, glad this could help, Biggy.

  12. JP
    February 28, 2011 at 2:42 pm

    Thank you much.

  13. prakash anandaraj
    March 2, 2011 at 6:26 am

    I have being trying to add a drawable but without any success, Until i came here. adding the android bug page for future reference http://code.google.com/p/android/issues/detail?id=2214

    • i82much
      March 2, 2011 at 4:41 pm

      Glad it was of use to you, prakash

  14. zhoubing
    April 2, 2011 at 3:51 am

    Thanks a lot.

  15. Miguel
    May 5, 2011 at 4:16 am

    Thanks so much, this would’ve driven me crazy! Tthanks to you I solved it in 5 min 🙂

  16. j0nSn0w
    May 27, 2011 at 3:40 am

    Thanks, this has been very useful. Shame on api’s documentation for this invalidating lack!

  17. Thank you
    June 4, 2011 at 9:33 am

    ❤ !

  18. SAverio
    July 12, 2011 at 11:09 am

    Thank you so much. It was very useful for me.

  19. Danilo
    August 3, 2011 at 10:56 pm

    Try this:

    final Drawable marker = mContext.getResources().getDrawable(R.drawable.android_msg_marker);
    item.setMarker(boundCenterBottom(marker));

  20. fjkd
    August 10, 2011 at 2:54 pm

    This was extremely helpful, thank you.

  21. ff
    September 8, 2011 at 5:00 am

    It’s useful. Thank you!

  22. January 11, 2012 at 10:30 pm

    This works however now my shadow is off to the left and higher than it is supposed to. The way I fixed this was to invert the boundaries in such way that i have the negative intrinsict width and height first and the third and fourth parameters are 0, 0..

    Thanks for the tip!

  23. Gica
    January 23, 2012 at 7:44 am

    I would like to display just the marker, without shadow. It is possible?

  24. Ana
    March 26, 2012 at 6:41 am

    Multiple overlays have been driving me crazy and making my app slow. Than you so much for this, you saved me!

    A.

  25. Aiden
    August 6, 2012 at 3:35 am

    Cheers buddy. very useful!

  26. August 21, 2012 at 5:16 pm

    Hey! I know this is kinda off topic however , I’d figured I’d ask.
    Would you be interested in trading links or maybe guest authoring a blog post or vice-versa?
    My blog discusses a lot of the same topics as yours and I think we could greatly benefit from each other.
    If you’re interested feel free to send me an e-mail. I look forward to hearing from you! Superb blog by the way!

    • Nicholas Dunn
      August 21, 2012 at 6:53 pm

      What’s the link to your blog?

  27. Schwaaner
    November 29, 2012 at 5:21 am

    Thanks, very useful

  28. March 18, 2013 at 7:43 pm

    Fantastic! Thank you for this! 😀

    As Danilo mentioned, you can use:

    item.setMarker(boundCenterBottom(marker));

    I actually used:

    item.setMarker(boundCenter(marker));

  29. March 23, 2013 at 5:28 am

    Hey would you mind sharing which blog platform you’re using? I’m going to start my
    own blog in the near future but I’m having a tough time deciding between BlogEngine/Wordpress/B2evolution and Drupal. The reason I ask is because your layout seems different then most blogs and I’m looking for something
    completely unique. P.S Sorry for being off-topic but I had to
    ask!

  30. April 1, 2013 at 7:34 am

    Great help! Thanks a ton! 🙂

    Cheers,
    Rohitesh

  1. No trackbacks yet.

Leave a reply to Ares Cancel reply