我在android中写了个在google地图上显示标记的er类。如下
package com.overlay;import android.app.AlertDialog;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Point;
import android.util.Log;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.Projection;
/**
 * 地图标记层
 */public class Marker extends Overlay {
private GeoPoint point = null;// 要插入标记的经纬度位置
private Bitmap bmp = null; // 标记使用的图标
private Point deviation = null; // 图标绘制偏移量 public Marker(GeoPoint point, Bitmap bmp, Point deviation) {
this.point = point;
this.bmp = bmp;
this.deviation = deviation;
} /**
 * 绘制图标
         */
@Override
public void draw(Canvas canvas, MapView mapView, boolean shadow) {
if (!shadow) {// 不是绘制shadow层
Projection projection = mapView.getProjection();
if (point != null && bmp != null) {
Point pos = projection.toPixels(point, null);
//需要添加偏移量
canvas.drawBitmap(bmp, pos.x + deviation.x, pos.y + deviation.y, null);
}
}
}
//@Override
/*public boolean onTap (GeoPoint point, MapView map){
Log.i("er", "OnTap Success");      
     return true;
}*/
@Override
public boolean onTouchEvent (android.view.MotionEvent e, MapView map){
Log.i("er", "OnTouch Success");
return true;
}
}
我想实现点击标记的时候弹出窗口。可是无论是onTap还是onTouchEvent,侦听的都是整个mapview的点击事件,也就是点击的不是标记这个层也会被捕捉到。请问各位有解决的方法吗?

解决方案 »

  1.   

    第五步:自定义地图的图层  接下来,我们需要为地图多增加一些自定义的功能,比如可以在地图上进行一些标注。为了实现这样的功能,我们可以继承Overlay这个类,这个类是一个基类,提供了可以在地图上添加图层的基本功能。而另外的选择是,我们可以继承itemzedOverlay这个类,  它提供了一种快捷的方法,可以把标记图片和相关的文本分配给特定的地理位置。ItemizedOverlay实例可以处理每一个OverlayItem(OverlayItem可以简单理解为在地图上的每一个标记)标记的绘制、放置、单击处理、焦点控制和布局优化。下面我们看代码:package com.javacodegeeks.android.googlemaps;
    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;
    public class CustomItemizedOverlay extends ItemizedOverlay<OverlayItem> {
       
       private ArrayList<OverlayItem> mapOverlays = new ArrayList<OverlayItem>();
       
       private Context context;
       
       public CustomItemizedOverlay(Drawable defaultMarker) {
            super(boundCenterBottom(defaultMarker));
       }
       
       public CustomItemizedOverlay(Drawable defaultMarker, Context context) {
            this(defaultMarker);
            this.context = context;
       }   @Override
       protected OverlayItem createItem(int i) {
          return mapOverlays.get(i);
       }   @Override
       public int size() {
          return mapOverlays.size();
       }
       
       @Override
       protected boolean onTap(int index) {
          OverlayItem item = mapOverlays.get(index);
          AlertDialog.Builder dialog = new AlertDialog.Builder(context);
          dialog.setTitle(item.getTitle());
          dialog.setMessage(item.getSnippet());
          dialog.show();
          return true;
       }
       
       public void addOverlay(OverlayItem overlay) {
          mapOverlays.add(overlay);
           this.populate();
       }}  在这个类中,需要在构造函数中使用Drawable类,这将被用作来绘制一个标记。此外,我们使用ArrayList去保存所有的Overlayitems,而createitem和size方法则容易理解了,分别是返回每一个Overlayitem和返回目前的所有标记的数目。而onTap方法则是在当某个标记在地图上真正标注时所触发的,比如当在触摸屏上点击时,也可以触发该事件。在这个例子中,我们只是通过弹出对话框的方法展示给用户看。最后,在addOverlay方法中,我们向标记数组mapOverlays中增加一个overlayitem标记,并且调用populate方法将其展示出来。  接下来我们看下如何使用上面的这个类,将代码修改如下:package com.javacodegeeks.android.googlemaps;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.MapController;
    import com.google.android.maps.MapView;
    import com.google.android.maps.Overlay;
    import com.google.android.maps.OverlayItem;public class GMapsActivity extends MapActivity {
        
        private MapView mapView;
        
        private static final int latitudeE6 = 37985339;
        private static final int longitudeE6 = 23716735;
        
        @Override
        public void onCreate(Bundle savedInstanceState) {
            
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            
            mapView = (MapView) findViewById(R.id.map_view);       
            mapView.setBuiltInZoomControls(true);
            
            List<OVERLAY> mapOverlays = mapView.getOverlays();
            Drawable drawable = this.getResources().getDrawable(R.drawable.icon);
            CustomItemizedOverlay itemizedOverlay = 
                 new CustomItemizedOverlay(drawable, this);
            
            GeoPoint point = new GeoPoint(latitudeE6, longitudeE6);
            OverlayItem overlayitem = 
                 new OverlayItem(point, "Hello", "I'm in Athens, Greece!");
            
            itemizedOverlay.addOverlay(overlayitem);
            mapOverlays.add(itemizedOverlay);
            
            MapController mapController = mapView.getController();
            
            mapController.animateTo(point);
            mapController.setZoom(6);
            
        }    @Override
        protected boolean isRouteDisplayed() {
            return false;
        }
        
    }  在上面的代码中,我们实例化了CustomItemizedOverlay类,并为其构造函数传入了Android默认的Drawable类的实例进行初始化,接下来,我们用一个预先定义好的经纬度去实例化一个GeoPoint类,GeoPoint类表示一个具体的位置。然后再用这个geopoint类的实例去初始化OverlayItem对象的实例,并且传入一段文本,这样就产生了一个完整的地图上的标记了,最后把这个标记加入到图层中去,这是通过调用CustomItemizedOverlay类的addOverlay去实现的,最后该标记就会出现在地图上了。  最后,我们调用了MapController这个工具类去控制地图的缩放,将地图缩放到由  GeoPoint类的实例指定区域的位置(使用的是animateTo方法),并用setZoom()方法指定了放大的级别。  运行程序后,可以看到在地图上只显示了指定区域大小的地图,并且看到了标记,当你点击标记时,可以看到弹出的对话框和显示的文字。
    ▲  总结  其实Android 搭配Google Map还能实现很多功能,比如GPS导航,结合SNS实现提供各类的LBS位置服务等,本文只是带领你初窥了Android 搭配Google Map的强大功能,更多的还有待读者去实践发现。