1 page.title=Hello, MapView 2 parent.title=Hello, Views 3 parent.link=index.html 4 @jd:body 5 6 <div class="special"> 7 <p>This tutorial requires that you have the Google Maps external library 8 installed in your SDK environment. By default the Android SDK includes the 9 Google APIs add-on, which in turn includes the Maps external library. If you 10 don't have the Google APIs SDK add-on, you can download it from this 11 location:</p> 12 13 <p style="margin-left:2em;"><a 14 href="http://code.google.com/android/add-ons/google-apis">http://code.google.com/android/add-ons/google-apis</a></p> 15 16 <p>The Google APIs add-on requires Android 1.5 SDK or later release. After 17 installing the add-on in your SDK, set your project properties to use the build 18 target called "Google APIs Add-on". See the instructions for setting a build 19 target in <a href="{@docRoot}guide/developing/eclipse-adt.html">Developing in 20 Eclipse with ADT</a> or <a 21 href="{@docRoot}guide/developing/other-ide.html">Developing in Other IDEs</a>, 22 as appropriate for your environment. </p> 23 24 <p>You will also need to use the android tool to set up an AVD that uses the 25 Google APIs deployment target. See <a 26 href="{@docRoot}guide/developing/tools/avd.html">Android Virtual Devices</a> for 27 more information. Once you have set up your environment, you will be able to 28 build and run the project described in this tutorial</a></p> 29 30 </div> 31 32 <p>A MapView allows you to create your own map-viewing Activity. 33 First, we'll create a simple Activity that can view and navigate a map. Then we will add some overlay items.</p> 34 35 <ol> 36 <li>Start a new project/Activity called HelloMapView. 37 38 <li>Because we're using the Google Maps library, 39 which is not a part of the standard Android library, we need to 40 declare it in the Android Manifest. Open the AndroidManifest.xml 41 file and add the following as a child of the <code><application></code> element: 42 43 <pre><uses-library android:name="com.google.android.maps" /></pre> 44 </li> 45 <li>We also need access to the internet in order to retrieve the Google Maps tiles, 46 so the application must request the {@link android.Manifest.permission#INTERNET INTERNET} permissions. 47 In the manifest file, add the following as a child of the <code><manifest></code> element: 48 <pre><uses-permission android:name="android.permission.INTERNET" /></pre> 49 </li> 50 <li>Now open the main layout file for your project. Define a layout with a com.google.android.maps.MapView 51 inside a android.widget.RelativeLayout: 52 53 <pre> 54 <?xml version="1.0" encoding="utf-8"?> 55 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 56 android:id="@+id/mainlayout" 57 android:orientation="vertical" 58 android:layout_width="fill_parent" 59 android:layout_height="fill_parent" > 60 61 <com.google.android.maps.MapView 62 android:id="@+id/mapview" 63 android:layout_width="fill_parent" 64 android:layout_height="fill_parent" 65 android:clickable="true" 66 android:apiKey="<em>Your Maps API Key</em>" 67 /> 68 69 </RelativeLayout> 70 </pre> 71 <p>The <code>clickable</code> attribute defines whether you want to allow user-interaction with the map. 72 In this case, we set it "true" so that the user can navigate.</p> 73 74 <p>The <code>apiKey</code> attribute holds the Google Maps API Key that proves your application and signer 75 certificate has been registered with the Google Maps service. Because MapView uses Google Maps data, this key is required 76 in order to receive the map data, even while you are developing. Registration is free and it only takes a couple 77 minutes to register your certificate and receive a Maps API Key. For instructions on getting a key, read 78 <a href="http://code.google.com/android/add-ons/google-apis/mapkey.html">Obtaining a Maps API Key</a>. 79 (For the purpose of this tutorial, you should register with the fingerprint of the SDK debug certificate.) 80 Once you've acquired the Maps API Key, insert it for the <code>apiKey</code> value.</p></li> 81 82 <li>Now open the HelloMapView.java file. For this Activity, we're going to extend the special sub-class of 83 Activity called MapActivity, so change the class declaration to extend 84 MapActivity, instead of Activity:</p> 85 86 <pre>public class HelloMapView extends MapActivity {</pre> 87 88 <li>The <code>isRouteDisplayed()</code> method is required, so add it inside the class: 89 <pre> 90 @Override 91 protected boolean isRouteDisplayed() { 92 return false; 93 } 94 </pre> 95 <p>You can actually run this now, but all it does is allow you to pan around the map.</p> 96 97 <li>Now go back to the HelloMapView class. We'll now retrieve the ZoomControls object from 98 the MapView and add it to our new layout element. First, at the top of the HelloMapView, 99 instantiate handles for the MapView and LinearLayout, plus a ZoomControl object: 100 <pre> 101 LinearLayout linearLayout; 102 MapView mapView; 103 </pre> 104 105 <li>Then initialize each of these in <code>onCreate()</code>. We'll capture the LinearLayout and 106 MapView through their layout resources. Then get the ZoomControls from the MapView:: 107 <pre> 108 mapView = (MapView) findViewById(R.id.mapview); 109 mapView.setBuiltInZoomControls(true); 110 </pre> 111 112 <p>By using the built-in zoom control provided by MapView, we don't have to do any of the work 113 required to actually perform the zoom operations. The controls will appear whenever the user 114 touches the map, then disappear after a few moments of inactivity.</p></li> 115 116 <li>Run it.</li> 117 </ol> 118 119 <hr/> 120 121 <p>So, we now have full interaction controls. All well and good, but what we really want our map 122 for is custom markers and layovers. Let's add some Overlay 123 objects to our map. To do this, we're going to 124 implement the ItemizedOverlay 125 class, which can manage a whole set of Overlay items for us.</p> 126 127 <ol> 128 <li>Create a new Java class named HelloItemizedOverlay that implements ItemizedOverlay. 129 130 <p>When using Eclipse, right-click the package name in the Eclipse Package Explorer, and select New > Class. Fill-in 131 the Name field as <em>HelloItemizedOverlay</em>. For the Superclass, enter 132 <em>com.google.android.maps.ItemizedOverlay</em>. Click the checkbox for <em>Constructors from 133 superclass</em>. Click Finish.</p></li> 134 135 <li> First thing, we need an OverlayItem ArrayList, in which we'll put each of the OverlayItem 136 objects we want on our map. Add this at the top of the HelloItemizedOverlay class: 137 138 <pre>private ArrayList<OverlayItem> mOverlays = new ArrayList<OverlayItem>();</pre></li> 139 140 <li>All the constructor does is define the default marker to be used on each of the OverlayItems. 141 In order for the Drawable to actually get drawn, it must have its bounds defined. And we want the 142 center-point at the bottom of the image to be the point at which it's attached to the map 143 coordinates. We handle all this with the boundCenterBottom() method. Wrap this around our 144 defaultMarker, so the super constructor call looks like this: 145 146 <pre>super(boundCenterBottom(defaultMarker));</pre></li> 147 148 <li>In order to add new OverlayItems to our ArrayList, we need a new public method. We'll handle 149 this with the following method: 150 151 <pre> 152 public void addOverlay(OverlayItem overlay) { 153 mOverlays.add(overlay); 154 populate(); 155 }</pre> 156 157 <p>Each time we add a new OverlayItem, we must call <code>populate()</code>, which will read each of out 158 OverlayItems and prepare them to be drawn.</p></li> 159 160 <li>In order for the <code>populate()</code> method to read each OverlayItem, it will make a request to 161 <code>createItem(int)</code>. We must define this method to properly read from our ArrayList. Replace the 162 existing contents of the createItem method with a <code>get()</code> call to our ArrayList: 163 164 <pre> 165 @Override 166 protected OverlayItem createItem(int i) { 167 return mOverlays.get(i); 168 } 169 </pre></li> 170 171 <li>We're also required to override the <code>size()</code> method. Replace the existing contents of the 172 method with a size request to our ArrayList: 173 174 <pre>return mOverlays.size();</pre></li> 175 </ol> 176 177 178 <p>That's it for the HelloItemizedOverlay class. We're now ready to use it.</p> 179 180 <hr/> 181 <p>Go back to the HelloMapView 182 class. We'll start by creating one OverlayItem, adding to an instance of our HelloItemizedOverlay, 183 and then adding this to the MapView.</p> 184 185 <img src="images/androidmarker.png" align="right" /> 186 <p>First, we need the image that we'll use for our map overlay. Here, we'll use the Android on the 187 right as our marker. Drag this image (or your own) to the res/drawable/ directory of your project workspace.</p> 188 189 <p>Now we're ready to work in the HelloMapView:</p> 190 191 <ol> 192 <li>First we need some more types. Add the following at the top of the HelloMapView class: 193 194 <pre> 195 List<Overlay> mapOverlays; 196 Drawable drawable; 197 HelloItemizedOverlay itemizedOverlay;</pre></li> 198 199 <li>Now pick up where we left off in the <code>onCreate()</code> method. Instantiate the 200 new fields: 201 202 <pre> 203 mapOverlays = mapView.getOverlays(); 204 drawable = this.getResources().getDrawable(R.drawable.androidmarker); 205 itemizedoverlay = new HelloItemizedOverlay(drawable);</pre> 206 207 <p>All overlay elements on a map are held by the MapView, so when we want to add some, we must 208 first retrieve the List with <code>getOverlays()</code> methods. We instantiate the Drawable, which will 209 be used as our map marker, by using our Context resources to get the Drawable we placed in 210 the res/drawable/ directory (androidmarker.png). Our HelloItemizedOverlay takes the Drawable in order to set the 211 default marker.</p></li> 212 213 <li>Now let's make our first OverlayItem by creating a GeoPoint 214 that defines our map coordinates, then pass it to a new OverlayItem: 215 216 <pre> 217 GeoPoint point = new GeoPoint(19240000,-99120000); 218 OverlayItem overlayitem = new OverlayItem(point, "", "");</pre> 219 220 <p>GeoPoint coordinates are based in microdegrees (degrees * 1e6). The OverlayItem takes this 221 GeoPoint and two strings. Here, we won't concern ourselves with the strings, which can display 222 text when we click our marker, because we haven't yet written the click handler for the OverlayItem.</p></li> 223 224 <li>All that's left is for us to add this OverlayItem to our collection in the HelloItemizedOverlay, 225 and add this to the List of Overlay objects retrieved from the MapView: 226 227 <pre> 228 itemizedoverlay.addOverlay(overlayitem); 229 mapOverlays.add(itemizedoverlay);</pre></li> 230 231 <li>Run it!</li> 232 </ol> 233 234 <p>We've sent our droid to Mexico City. Hola, Mundo!</p> 235 <p>You should see the following:</p> 236 <img src="images/hello-mapview.png" width="150px" /> 237 238 <p>Because we created our ItemizedOverlay class with an ArrayList, we can continue adding new 239 OverlayItems. Try adding another one. Before the <code>addOverlay()</code> method is called, add these lines:</p> 240 <pre> 241 GeoPoint point2 = new GeoPoint(35410000, 139460000); 242 OverlayItem overlayitem2 = new OverlayItem(point2, "", ""); 243 </pre> 244 <p>Run it again... We've sent a new droid to Tokyo. Sekai, konichiwa!</p> 245 246