Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> 對populate()方法的理解

對populate()方法的理解

編輯:關於Android編程


在開發地圖的應用中,我們很多時候需要在地圖上繪制一些文本,圖標信息(比如當前位置的圖標,比如某個區域內肯德基店的所有興趣點)
為了能夠在地圖上繪制我們需要的信息(比如圖片),我們需要知道圖層的概念。(就像photoshop裡的圖層)
接下來我們需要利用API接口實現我們的功能(我們這裡采用的是高德的API,高德API開發包可自行在官網上下載)
高德API提供了一個基類Overlay,用於在地圖上繪圖。我們可以繼承自該類,重寫draw()方法,調用canvas(畫布)的一些方法(比如drawText,drawCircle,drawBitmap),可以在地圖上畫出許多圖形來。這些東西在上一章中有過介紹就不在啰嗦了。
API裡還有一個抽象類,它叫做ItemizedOverlay<OverlayItem>,它繼承自Overlay,所以它也是一個圖層類。該類最大的特點是,它可以描繪出一組興趣點(POI)出來。繼承該抽象類,必須復寫三個方法,首先是一個構造方法,它含有一個參數Drawable,該參數是一個圖形資源,實則上就是負責顯示在地圖上的一個圖標。另外兩個方法分別是
[java] 
@Override 
protected OverlayItem createItem(int i) { 
     

 
@Override 
public int size() { 
     

方法createItem中的返回類型是OverlayItem,該類封裝有地理點(GeoPoint),片段信息(Snippet)以及標題(Title),我們通常是這樣來得到一個OverlayItem對象的:
[java] 
OverlayItem item = new OverlayItem(gp, "title","snippet");//gp的類型是GeoPoint 

在講第二個方法前,我們首先看看如何繼承ItemizedOverlay<OverlayItem>,假設實現類名為DemoItemizedOverlay
在自己的實現類中,對於字段,我們需要添加一個List<OverlayItem>列表:
[java
List<OverlayItem> overlay_list = new ArrayList<OverlayItem>(); 
注意該列表的元素類型是OverlayItem。
接下來是重寫構造方法:
[java] 
public DemoItemizedOverlay(Drawable d) { 
    super(boundCenterBottom(d)); 

 
方法boundCenterBottom的作用是為了將(0,0)點置於圖標的底邊中點。
 而方法boundCenter的作用是將(0,0)置於圖標中央。

然後是重寫兩個必寫方法:
[java] 
@Override 
protected OverlayItem createItem(int i) { 
    return over_list.get(i); 

 
@Override 
public int size() { 
    return over_list.size(); 

如果想在圖標附近添加文本,我們需要復寫draw方法:
[java] 
@Override 
public void draw(Canvas canvas, MapView mapView, boolean shadow) { 
    for(int i=0; i< size(); i++) { 
        OverlayItem item = createItem(i); 
        GeoPoint gp = item.getPoint(); 
        Point mPoint = new Point(); 
        Projection proj = mapView.getProjection(); 
        proj.toPixels(gp, mPoint); 
        Paint mPaint = new Paint(); 
        mPaint.setColor(Color.BLUE); 
        mPaint.setAntiAlias(true);  //抗鋸齒 
        canvas.drawText("圖標" + (i+1), mPoint.x, mPoint.y-30, mPaint); 
         
    } 
    super.draw(canvas, mapView, shadow); 

注意到列表內容是空的,我們需要增加方法來向列表添加內容和刪除內容
[java] 
 * 添加一個Overlay
 */ 
public void addOverlay(OverlayItem overlay) { 
    over_list.add(overlay); 
    populate(); 

/**
 * 刪除一個Overlay
 */ 
public void dropOverlay(OverlayItem item) { 
    if(over_list.contains(item)) { 
        over_list.remove(item); 
        populate(); 
    } 


關鍵點來了,有沒有注意到populate()方法,我們可以看看該方法的定義位置:
[java] 
void com.amap.mapapi.map.ItemizedOverlay.populate() 

說明該方法是ItemizedOverlay類裡的。
我們看看官方文檔是怎麼描述該方法的。
[html] 
在一個新的ItemizedOverlay對象上執行所有操作的工具方法。子類通過createItem(int)方法提供item。一旦有了數據,子類在調用其它方法前,首先調用該方法。 

我們在回過頭來看看那兩個必寫方法,createItem()和size()方法。
當我們在向列表裡添加或者刪除(各種操作)方法後,必須首先調用populate()方法。調用populate()方法後,接下來就會自動調用createItem()方法和size()方法,這樣列表裡才真正有了數據。為了驗證這一點,我自己做了一個測試。
測試大概是這樣的, 我首先創建了DemoItemizedOverlay對象,然後創建了4個OverlayItem對象,接著調用方法addOverlay把它們加入到列表中。如果addOverlay方法裡含有populate()方法,那麼在測試地圖上,我們可以看到有4個圖標以及文本信息。然後如果我把populate()方法刪掉,此時會拋出異常終止信息,查看LogCat日志:

 


之所以會拋出空指針異常,是因為沒有調用populate()方法,所以也不會調用createItem()方法,因此雖然調用了addOverlay方法,但是實際上並沒有往列表裡添加Overlay,因此會拋出NullPointerException。

我們看下createItem方法的描述:
[plain]
createItem 
 
protected abstract Item createItem(int i) 
子類通過該方法創建實體item。該item只能從populate()開始調用,並且緩存起來待以後使用。 
參數: 
i - 實體item對象。 
返回: 
創建的實體item。 

下面是測試的MainActivity代碼:

[java] 
package com.example.itemizedoverlaytest; 
 
import java.util.ArrayList; 
import java.util.List; 
 
import android.content.Context; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.graphics.Point; 
import android.graphics.drawable.Drawable; 
import android.os.Bundle; 
import android.widget.Toast; 
 
import com.amap.mapapi.core.GeoPoint; 
import com.amap.mapapi.core.OverlayItem; 
import com.amap.mapapi.map.ItemizedOverlay; 
import com.amap.mapapi.map.MapActivity; 
import com.amap.mapapi.map.MapController; 
import com.amap.mapapi.map.MapView; 
import com.amap.mapapi.map.Overlay; 
import com.amap.mapapi.map.Projection; 
 
public class MainActivity extends MapActivity { 
 
    private MapView mapView; 
     
    private Drawable d; 
     
    private MapController controller; 
     
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
         
        //this.setMapMode(MAP_MODE_VECTOR); //設置為矢量圖s 
         
        setContentView(R.layout.activity_main); 
         
        mapView = (MapView)findViewById(R.id.mapView); 
         
        mapView.setBuiltInZoomControls(true);   //開啟縮放控件 
         
        controller = mapView.getController();   //得到控制對象 
         
//      mapView.setSatellite(true);             //設置衛星模式 
         
        GeoPoint gp = new GeoPoint((int) (30.227123 * 1E6), 
                (int) (120.040687 * 1E6));  //工大 
         
        controller.setCenter(gp); 
         
        controller.setZoom(10); 
         
        d = getResources().getDrawable(R.drawable.marker_gpsvalid); 
         
    //  d.setBounds(0, 0, right, bottom) 
         
        List<Overlay> map_list = mapView.getOverlays(); 
         
        DemoItemizedOverlay demo = new DemoItemizedOverlay(d, this); 
        GeoPoint gp1 = new GeoPoint((int) (30.227123 * 1E6), 
                (int) (120.040687 * 1E6)); 
        OverlayItem item1 = new OverlayItem(gp1, "title1","snippet1"); 
        demo.addOverlay(item1); 
         
        GeoPoint gp2 = new GeoPoint((int) (30.237123 * 1E6), 
                (int) (120.050687 * 1E6)); 
        OverlayItem item2 = new OverlayItem(gp2, "title2","snippet2"); 
        demo.addOverlay(item2);  
         
        GeoPoint gp3 = new GeoPoint((int) (30.247123 * 1E6), 
                (int) (120.060687 * 1E6)); 
        OverlayItem item3 = new OverlayItem(gp3, "title3","snippet3"); 
        demo.addOverlay(item3);  
         
        map_list.add(demo); 
     
        GeoPoint gp4 = new GeoPoint((int) (30.257123 * 1E6), 
                (int) (120.070687 * 1E6)); 
        OverlayItem item4 = new OverlayItem(gp4, "title4","snippet4"); 
        demo.addOverlay(item4);  
         
        demo.dropOverlay(item2); 
    } 
     
    public class DemoItemizedOverlay extends ItemizedOverlay<OverlayItem> { 
 
        private List<OverlayItem> over_list = new ArrayList<OverlayItem>(); 
 
        private Context mContext;           //上下文 
         
        public DemoItemizedOverlay(Drawable d) { 
            super(boundCenterBottom(d)); 
        } 
 
        public DemoItemizedOverlay(Drawable d,Context c) { 
            this(d); 
            mContext = c; 
        } 
         
        @Override 
        public void draw(Canvas canvas, MapView mapView, boolean shadow) { 
            for(int i=0; i< size(); i++) { 
                OverlayItem item = createItem(i); 
                GeoPoint gp = item.getPoint(); 
                Point mPoint = new Point(); 
                Projection proj = mapView.getProjection(); 
                proj.toPixels(gp, mPoint); 
                Paint mPaint = new Paint(); 
                mPaint.setColor(Color.BLUE); 
                mPaint.setAntiAlias(true);  //抗鋸齒 
                canvas.drawText("圖標" + (i+1), mPoint.x, mPoint.y-30, mPaint); 
                 
            } 
            super.draw(canvas, mapView, shadow); 
        } 
 
        @Override 
        protected boolean onTap(int i) { 
            OverlayItem item = over_list.get(i); 
            Toast.makeText(mContext,"片段信息:" + item.getSnippet() + "\n標題:" + item.getTitle(),Toast.LENGTH_SHORT).show(); 
            return super.onTap(i); 
        } 
 
        @Override 
        protected OverlayItem createItem(int i) { 
            return over_list.get(i); 
        } 
 
        @Override 
        public int size() { 
            return over_list.size(); 
        } 
         
        /**
         * 添加一個Overlay
         */ 
        public void addOverlay(OverlayItem overlay) { 
            over_list.add(overlay); 
            populate(); 
        } 
        /**
         * 刪除一個Overlay
         */ 
        public void dropOverlay(OverlayItem item) { 
            if(over_list.contains(item)) { 
                over_list.remove(item); 
                populate(); 
            } 
        } 
    } 

最後別忘了加相應的權限,以及在安卓清單文件中注冊該Activity。
需要項目資源的可點擊:http://download.csdn.net/detail/czjuttsw/4726692

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved