Home | History | Annotate | Download | only in views
      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>&lt;application></code> element:
     42 
     43     <pre>&lt;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>&lt;manifest></code> element:
     48     <pre>&lt;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 &lt;?xml version="1.0" encoding="utf-8"?>
     55 &lt;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     &lt;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 &lt;/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 &#64;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&lt;OverlayItem> mOverlays = new ArrayList&lt;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 &#64;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&lt;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