2010-03-31 19 views
14

Ho una MapActivity relativamente semplice che sto cercando di mostrare un elenco di "campi" all'interno di una determinata area della mappa. Ho creato una sottoclasse personalizzata di OverlayItem chiamata CampOverlayItem, una classe personalizzata ItemizedOverlay denominata CampsOverlay che restituisce CampOverlayItems e ovviamente una sottoclasse MapActivity che popola la mappa.NullPointerException in ItemizedOverlay.getIndexToDraw

Sto prelevando i dati di sovrapposizione da un database utilizzando un AsyncTask come creato nella mia attività. AsyncTask viene attivato da un ViewTreeObserver.OnGlobalLayoutListener collegato a MapView.

Nel metodo OnPostExecute del AsyncTask, creo una nuova istanza della mia classe CampsOverlay e passare un elenco dei campi restituiti dalla database (che sono recuperati in doInBackground). Quindi chiamo:

mapView.getOverlays().add(newOverlay); 

dove newOverlay è il CampsOverlay che ho appena creato. Tutto questo codice viene eseguita senza errori, ma quando la mappa tenta di disegnare se stesso, ho un NullPointerException con la seguente analisi dello stack:

java.lang.NullPointerException 
    at 
com.google.android.maps.ItemizedOverlay.getIndexToDraw(ItemizedOverlay.java: 
211) 
    at 
com.google.android.maps.ItemizedOverlay.draw(ItemizedOverlay.java:240) 
    at com.google.android.maps.Overlay.draw(Overlay.java:179) 
    at com.google.android.maps.OverlayBundle.draw(OverlayBundle.java: 
42) 
    at com.google.android.maps.MapView.onDraw(MapView.java:476) 
    at android.view.View.draw(View.java:6274) 
    at android.view.ViewGroup.drawChild(ViewGroup.java:1526) 
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1256) 
    at android.view.ViewGroup.drawChild(ViewGroup.java:1524) 
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1256) 
    at android.view.View.draw(View.java:6277) 
    at android.widget.FrameLayout.draw(FrameLayout.java:352) 
    at android.view.ViewGroup.drawChild(ViewGroup.java:1526) 
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1256) 
    at android.view.ViewGroup.drawChild(ViewGroup.java:1524) 
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1256) 
    at android.view.ViewGroup.drawChild(ViewGroup.java:1524) 
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1256) 
    at android.view.ViewGroup.drawChild(ViewGroup.java:1524) 
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1256) 
    at android.view.ViewGroup.drawChild(ViewGroup.java:1524) 
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1256) 
    at android.view.View.draw(View.java:6277) 
    at android.widget.FrameLayout.draw(FrameLayout.java:352) 
    at android.view.ViewGroup.drawChild(ViewGroup.java:1526) 
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1256) 
    at android.view.View.draw(View.java:6277) 
    at android.widget.FrameLayout.draw(FrameLayout.java:352) 
    at com.android.internal.policy.impl.PhoneWindow 
$DecorView.draw(PhoneWindow.java:1883) 
    at android.view.ViewRoot.draw(ViewRoot.java:1332) 
    at android.view.ViewRoot.performTraversals(ViewRoot.java:1097) 
    at android.view.ViewRoot.handleMessage(ViewRoot.java:1613) 
    at android.os.Handler.dispatchMessage(Handler.java:99) 
    at android.os.Looper.loop(Looper.java:123) 
    at android.app.ActivityThread.main(ActivityThread.java:4203) 
    at java.lang.reflect.Method.invokeNative(Native Method) 
    at java.lang.reflect.Method.invoke(Method.java:521) 
    at com.android.internal.os.ZygoteInit 
$MethodAndArgsCaller.run(ZygoteInit.java:791) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:549) 
    at dalvik.system.NativeStart.main(Native Method) 

Perché sembra particolarmente rilevante, ecco il codice per il mio ItemizedOverlay sottoclasse:

public class CampsOverlay extends ItemizedOverlay<CampOverlayItem> { 
    private ArrayList<Camp> camps = null; 

    public CampsOverlay(Drawable defaultMarker, ArrayList<Camp> theCamps) 
{ 
     super(defaultMarker); 
     this.camps = theCamps; 
    } 

    @Override 
    protected CampOverlayItem createItem(int i) { 
     Camp camp = camps.get(i); 
     CampOverlayItem item = new CampOverlayItem(camp); 
     return item; 
    } 

    @Override 
    protected boolean onTap(int index) { 
     // TODO Auto-generated method stub 
     return super.onTap(index); 
    } 

    @Override 
    public int size() { 
     return camps.size(); 
    } 

} 

Qualcuno ha idea di cosa potrebbe accadere qui? Ho provato per verificare che tutto ciò su cui ho il controllo non sia nullo. Posso fornire più codice se necessario.

risposta

20

Non vedo dove si chiama populate() sul CampsOverlay.

Here is a sample project che mostra il caricamento asincrono degli elementi di sovrapposizione - forse vi darà alcune idee, se populate() non è il problema.

+0

Hai perfettamente ragione, grazie Mark. Penseresti che avrei guardato più attentamente il tuo codice di esempio prima di fare questa domanda. Ora devo solo capire perché gli elementi di sovrapposizione non vengono visualizzati;) – lyricsboy

3

Ha ragione. È necessario chiamare populate() per popolare l'overlay. Si consiglia di creare tutti gli elementi di sovrapposizione nel costruttore, chiamare popola e in createItem è sufficiente restituire l'elemento da un elenco.

+0

C'è un vantaggio nella creazione degli elementi nel costruttore anziché uno alla volta all'interno di createItem?Dalla mia lettura della documentazione, ItemizedOverlay memorizzerà nella cache i risultati di createItem, quindi non è necessario necessariamente aggrapparsi anche a quelli della mia sottoclasse. – lyricsboy

2

"Ora devo solo capire il motivo per cui gli elementi di sovrapposizione non compaiono"

In caso non lo è perché è necessario utilizzare una funzione statica sul tuo Drawable che spiegherà come è il tuo indicatore posizionato

È possibile utilizzare questo, nel vostro CampsOverlay costruttore:

super(boundCenter(defaultMarker));

Questo indica che l'origine del vostro Drawable è il centro. È inoltre possibile utilizzare boundCenterBottom() per indicare che l'origine è il centro inferiore di Drawable.

Problemi correlati