ItemizedOverlay Demo Example OverlayItem Overlay

来源:互联网 发布:0基础学编程 知乎 编辑:程序博客网 时间:2024/05/17 00:17
Differecnes between ItemizedOverlay and Overlay class 

Overlay is a general overlay. ItemizedOverlay is a subclass that makes it easier to create an overlay that is a discrete series of marked points on the map. So, if you are trying to show a bus route, or shade a region, or something like that, Overlay is the class you want. If you are trying to show a collection of restaurants, or churches, or whatever, ItemizedOverlay works. 

Note, though, that ItemizedOverlay is designed for modest numbers of points (e.g., dozens). If you have a large number of points, you may need to create your own Overlay just for performance reasons. 
下面给出一个例子介绍ItemizedOverlay如何使用,代码具有自我解释功能。 
<?xml version="1.0" encoding="UTF-8" ?><RelativeLayout android:background="#ff000000"android:padding="3.0dip" android:layout_width="wrap_content"android:layout_height="wrap_content" xmlns:android="http://schemas.android.com/apk/res/android"><com.google.android.maps.MapViewandroid:id="@+id/mapView" android:clickable="true"android:layout_width="fill_parent" android:layout_height="fill_parent"android:layout_alignParentBottom="true"android:apiKey="0K834befj1r6RIspWAzNY9vUykEaxjEm3He4VGA" />  <!-- 换成自己的apiKey --></RelativeLayout>

package com.test;import java.util.ArrayList;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 Main extends MapActivity {    MapView mapView;    GeoPoint nanjing = new GeoPoint((int)(32.04 * 1E6), (int)(118.78 * 1E6));    GeoPoint hangzhou = new GeoPoint((int)(30.26 * 1E6), (int)(120.19 * 1E6));    GeoPoint shanghai = new GeoPoint((int)(31.22 * 1E6), (int)(121.48 * 1E6));    ArrayList<OverlayItem> list;    ShowOverlay sol;        public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);                mapView = (MapView)findViewById(R.id.mapView);        mapView.getController().animateTo(hangzhou);        mapView.setBuiltInZoomControls(true);        mapView.getController().setZoom(8);                //-----------------创建OverlayItem链表----------------        list  = new ArrayList<OverlayItem>();        OverlayItem o1 = new OverlayItem(nanjing, "title", "snippet");        OverlayItem o2 = new OverlayItem(hangzhou, "title", "snippet");        OverlayItem o3 = new OverlayItem(shanghai, "title", "snippet");        list.add(o1);        list.add(o2);        list.add(o3);                //-----------------获取图标M-----------------------------        Drawable drawable = getApplicationContext().getResources().getDrawable(R.drawable.icon);                //-----------------new ShowOverlay对象-------------------        sol = new ShowOverlay(drawable, list);                //------------------得到MapView图层Overlays---------------        List<Overlay> overlays = mapView.getOverlays();                //------------------将图层添加到MapView---------------        overlays.add(sol);    }    @Override    protected boolean isRouteDisplayed() {        return false;    }}

package com.test;import java.util.ArrayList;import android.graphics.Canvas;import android.graphics.drawable.Drawable;import android.util.Log;import android.view.KeyEvent;import com.google.android.maps.ItemizedOverlay;import com.google.android.maps.MapView;import com.google.android.maps.OverlayItem;public class ShowOverlay extends ItemizedOverlay<OverlayItem> {    private final static String TAG = "ShowOverlay";    private ArrayList<OverlayItem> l;    public ShowOverlay(Drawable defaultMarker) {        super(defaultMarker);    }    public ShowOverlay(Drawable defaultMarker, ArrayList<OverlayItem> l) {        super(boundCenterBottom(defaultMarker));        //直到使用boundCenterBotton(defaultMarker),我的图标才显示出来        this.l = l;        //populate() 放在这里为什么合理        //populate() 会创建这一层中包含的每一个overlay item          //api: The subclass should call populate as soon as it has data, before        // anything else gets called.        Log.d(TAG, "before populate()");        populate();        //populate() 首先调用size(),根据size大小,决定调用createItem()的次数,创建OverlayItem列表        Log.d(TAG, "after populate()");    }    protected OverlayItem createItem(int i) {        Log.d(TAG, "createItem()" + i);        return l.get(i);    }    public int size() {        Log.d(TAG, "size = " + l.size());        return l.size();    }    protected int getIndexToDraw(int i) {        Log.d(TAG, "getIndexToDraw" + i);        return super.getIndexToDraw(i);    }    // The marker will be drawn twice for each Item in the Overlay--once in the    // shadow phase, skewed and darkened, then again in the non-shadow phase    public void draw(Canvas canvas, MapView mapview, boolean flag) {        Log.d(TAG, "before super draw");        super.draw(canvas, mapview, flag);        //首先取得size,然后使用getIndexToDraw获得画item的顺序        Log.d(TAG, "after super draw");    }    protected boolean onTap(int i) {        Log.d(TAG, "onTap" + i);        return super.onTap(i);    }    // it works just with marker(icon)    public boolean onKeyUp(int i, KeyEvent keyevent, MapView mapview) {        Log.d(TAG, "onkeyup");        return super.onKeyUp(i, keyevent, mapview);    }}

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"      package="com.test"      android:versionCode="1"      android:versionName="1.0">    <uses-sdk android:minSdkVersion="7" />    <application android:icon="@drawable/icon" android:label="@string/app_name">    <uses-library android:name="com.google.android.maps" />             <!-- 注意 -->        <activity android:name=".Main"                  android:label="@string/app_name">            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>    </application>    <uses-permission android:name="android.permission.INTERNET" />  <!-- 注意 --></manifest>

从logcat大致可以看出,ItemizedOverlay中方法的调用关系。其中的draw方法的调用不是很透明,一开始怎么调那么多次draw方法啊??? 
点击一下界面,会重复调用draw方法,点击不放,调用两次,放开点击,又调用两次。代码中的draw方法也注释了marker会被画两次,一次阴影阶段,一次非阴影阶段。这与点击不放会调用两次可以解释。 

还有我猜哈,就是这个点击不放的事件由mapView接收,然后以类似广播的方式通知所有的overlay,叫他们重新画。 


转贴:http://menuz.iteye.com/blog/1236828