ItemizedOverlay Demo Example OverlayItem Overlay

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.MapView
		android: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,叫他们重新画。


如需源码,站内短信我。





你可能感兴趣的:(android,performance,overlay,itemizedoverlay,differecnes)