Sunday, December 23, 2012

Add Information/Object to Marker in Google Maps Android API v2

As some of you might know, Google recently launched a completely new API for Google Maps on Android. Therefor, I'm going to post some tutorials on this. I'm going to talk about linking an object to a Marker. If you haven't tried the new API yet, get started by reading this post on the Android Developers Blog.

Let's start by making a quick example application that works with a self-made class called EventInfo. This class holds a LatLng-object for the location, a String for the name and let's put in a Date.
I've created a class called MainMapFragment that extends the MapFragment of Google Play Services. Here's the code for that:
public class MainMapFragement extends MapFragment {

 

 public Marker placeMarker(EventInfo eventInfo) {

  Marker m  = getMap().addMarker(new MarkerOptions()

   .position(eventInfo.getLatLong())

   .title(eventInfo.getName()));

  

  return m;

 }

}
I'm going to show you why i've made the placeMarker() method in just a second.
First let us have a look at our xml layout file:
<?xml version="1.0" encoding="utf-8"?>

 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"

  android:id="@+id/map"

  android:layout_width="match_parent"

  android:layout_height="match_parent"/>
It's just that simple, so let's have a look at our MainActivity where every thing is managed:
public class MainActivity extends Activity {



 private MainMapFragement mapFragment;

 private HashMap<Marker, EventInfo> eventMarkerMap;



 @Override

 protected void onCreate(Bundle savedInstanceState) {

  super.onCreate(savedInstanceState);

  setContentView(R.layout.activity_main);

  mapFragment = new MainMapFragement();

  FragmentTransaction ft = getFragmentManager().beginTransaction();

  ft.add(R.id.map, mapFragment);

  ft.commit();

  

 }

 

 @Override

 protected void onStart() {

  super.onStart();

  setUpEventSpots();

 }







 private void setUpEventSpots() {

  // I'm going to make 2 EventInfo objects and place them on the map

  EventInfo firstEventInfo = new EventInfo(new LatLng(50.154, 4.35), "Right now - event", new Date());

  EventInfo secondEventInfo = new EventInfo(new LatLng(51.25, 4.15), "Future Event", new Date(1032, 5, 25));

  //this date constructor is deprecated but it's just to make a simple example

  

  

  

  Marker firstMarker = mapFragment.placeMarker(firstEventInfo);

  Marker secondMarker = mapFragment.placeMarker(secondEventInfo);

  

  eventMarkerMap = new HashMap<Marker, EventInfo>();

  eventMarkerMap.put(firstMarker, firstEventInfo);

  eventMarkerMap.put(secondMarker, secondEventInfo);

  

  //add the onClickInfoWindowListener

  mapFragment.getMap().setOnInfoWindowClickListener(new OnInfoWindowClickListener() {

   

   @Override

   public void onInfoWindowClick(Marker marker) {

    EventInfo eventInfo = eventMarkerMap.get(marker);

    Toast.makeText(getBaseContext(),

      "The date of " + eventInfo.getName() + " is " + eventInfo.getSomeDate().toLocaleString(),

      Toast.LENGTH_LONG).show();

    

   }

  });

  

 }



}
So in the onCreate() method, I'm making a private MainMapFragment object that I place in my FrameLayout of the Activity. Then I'm setting up 2 simple EventInfo objects and call the method placeMarker() for each object. This places a Marker with the name as title and returns that Marker.

Next up is the important part. We're going to make a HashMap that stores the EventInfo object with the Marker as key. That way, we have linked the Marker with the object. To show you what we can do with this, we have to implement the onClickInfoWindowListener on the map of our MainMapFragment.
We are expected to implement the method onInfoWindowClick() that gives us the Marker object. We get the clicked marker and search the correct EventInfo object in the HashMap.
To show a result, I just made a simple Toast message that tells us the name of the EventInfo and the date.

Here are some screenshots:


Important note: I've called the setUpEventSpots() method in the onStart() method. This is because the map needs to get loaded first and you'd get a NullPointerException on getMap() if I would called it in the onCreate() method.

Feel free to leave comments below