bill在【如何在Android中使用GoogleMap API】一文中介绍了在Android开发中使用GoogleMap API所需的准备工作,本文将在该准备工作就绪的前提下介绍如何在GoogleMap上显示自定义的地标。如下图所示:

其实Google Map中的地标(或者说图标更贴切)就是位于地图图层上的一个新图层,我们只需要简单的将自己的图标(或者是图标集合)添加到Google Map内置的图标图层里去即可。
以上文中的HelloGoogleMap为例
activity_main.xml
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent" >
-
- <com.google.android.maps.MapView
- android:id="@+id/mapview"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:apiKey="你所获得的API KEY"
- android:clickable="true" />
-
-
</RelativeLayout>
- package com.billhoo.study.hellogooglemaps;
-
- import java.util.List;
-
- import android.graphics.drawable.Drawable;
- import android.os.Bundle;
-
- import com.google.android.maps.GeoPoint;
- import com.google.android.maps.MapActivity;
- import com.google.android.maps.MapView;
- import com.google.android.maps.Overlay;
- import com.google.android.maps.OverlayItem;
-
- public class MainActivity extends MapActivity {
- MapView mMapView = null;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- mMapView = (MapView) findViewById(R.id.mapview);
- mMapView.setBuiltInZoomControls(true);
-
- @Override
- protected boolean isRouteDisplayed() {
- return false;
- }
- }
上述代码能够在MainActivity中显示GoogleMap,接下来我们将编写自定义的图标类HelloItemizedOverlay,本类维护一个图标集合,并在需要时由用户将本类对象添加进GoogleMap内置的图标集合中去,从而实现地图上图标的显示以及其他相关操作。代码如下:
- package com.billhoo.study.hellogooglemaps;
-
- import java.util.ArrayList;
-
- import android.app.AlertDialog;
- import android.content.Context;
- import android.graphics.drawable.Drawable;
-
- import com.google.android.maps.ItemizedOverlay;
- import com.google.android.maps.OverlayItem;
-
- @SuppressWarnings("rawtypes")
- public class HelloItemizedOverlay extends ItemizedOverlay {
- private ArrayList<OverlayItem> mOverlayItems = new ArrayList<OverlayItem>();
- private Context mContext = null;
-
- public HelloItemizedOverlay(Drawable defaultMarker) {
- super(boundCenter(defaultMarker));
- }
-
- public HelloItemizedOverlay(Drawable defaultMarker, Context context) {
- super(boundCenter(defaultMarker));
- mContext = context;
- }
-
- @Override
- protected OverlayItem createItem(int i) {
- return mOverlayItems.get(i);
- }
-
- @Override
- public int size() {
- return mOverlayItems.size();
- }
-
-
-
-
- @Override
- protected boolean onTap(int index) {
- OverlayItem item = mOverlayItems.get(index);
- AlertDialog.Builder dialog = new AlertDialog.Builder(mContext);
- dialog.setTitle(item.getTitle());
- dialog.setMessage(item.getSnippet());
- dialog.show();
- return true;
- }
-
-
-
-
-
-
- public void addOverlay(OverlayItem overlay) {
- mOverlayItems.add(overlay);
- populate();
- }
- }
上述代码算是一个固定结构,期间重载了父类ItemizedOverlay的createItem(int i)、size()以及onTap(int index)方法,并且新增了一个用于添加新图标的addOverlay(OverlayItem overlay)方法(今后可以根据自己的需要增加诸如clear()、remove()等常用方法)。
接下来需要做的事情便是利用上述工具类进行图标的添加了,修改后的MainActivity如下:
- package com.billhoo.study.hellogooglemaps;
-
- import java.util.List;
-
- import android.graphics.drawable.Drawable;
- import android.os.Bundle;
-
- import com.google.android.maps.GeoPoint;
- import com.google.android.maps.MapActivity;
- import com.google.android.maps.MapView;
- import com.google.android.maps.Overlay;
- import com.google.android.maps.OverlayItem;
-
- public class MainActivity extends MapActivity {
- private MapView mMapView = null;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- mMapView = (MapView) findViewById(R.id.mapview);
- mMapView.setBuiltInZoomControls(true);
-
- List<Overlay> mapOverlays = mMapView.getOverlays();
- Drawable drawable = this.getResources().getDrawable(
- R.drawable.cur_location);
- HelloItemizedOverlay itemizedOverlays = new HelloItemizedOverlay(
- drawable, this);
-
- GeoPoint point1 = new GeoPoint((int) (35.422006 * 1E6),
- (int) (104.084095 * 1E6));
- OverlayItem overlayItem1 = new OverlayItem(point1, "我的第一个地标", "随便找个点");
-
- GeoPoint point2 = new GeoPoint((int) (35.4 * 1E6), (int) (139.46 * 1E6));
- OverlayItem overlayItem2 = new OverlayItem(point2, "这是第二个图标", "随便找的地点");
-
- itemizedOverlays.addOverlay(overlayItem1);
- itemizedOverlays.addOverlay(overlayItem2);
-
- mapOverlays.add(itemizedOverlays);
- }
-
- @Override
- protected boolean isRouteDisplayed() {
- return false;
- }
- }
到此为止,在GoogleMap上显示自定义图标的基础部分已经全部完工,运行模拟器看看效果吧。

依次点击第一个以及第二个气泡,便会弹出我们之前设置好的提示信息


细心的朋友会发现,气泡的阴影部分怎么没有正确显示?别忙,请在代码段中加入如下处理
- ...
- OverlayItem overlayItem2 = new OverlayItem(point2, "这是第二个图标", "随便找的地点");
-
-
- Drawable marker = this.getResources().getDrawable(
- R.drawable.cur_location);
- int w = marker.getIntrinsicWidth();
- int h = marker.getIntrinsicHeight();
- marker.setBounds(-w / 2, -h, w / 2, 0);
-
- overlayItem1.setMarker(marker);
-
-
- itemizedOverlays.addOverlay(overlayItem1);
- ...
再次运行,发现第一个点的阴影已经正确显示了。

到此,bill已经将图标的添加介绍完毕,其中还包括了自己遇到的阴影错位问题的修正方法。但是,Android Google Map的陷阱还有很多,这也是bill这段时间以来一直在折腾的原因。接下来的文章,bill将一一向大家分享这些陷阱的解决方案,希望能够帮到那些像bill之前那样,对其中各种莫名其妙的异常或错误百思不得其解的朋友。
本文转自Bill_Hoo 51CTO博客,原文链接:http://blog.51cto.com/billhoo/970811,如需转载请自行联系原作者