2010-03-31 14 views
14

Tengo una MapActivity relativamente simple que estoy tratando de mostrar una lista de "campos" dentro de una región determinada del mapa. Creé una subclase personalizada de OverlayItem llamada CampOverlayItem, una personalizada ItemizedOverlay llamada CampsOverlay que devuelve CampOverlayItems, y , por supuesto, una subclase MapActivity que rellena el mapa.NullPointerException en ItemizedOverlay.getIndexToDraw

Estoy extrayendo los datos de superposición de una base de datos utilizando una AsyncTask como creada en mi actividad. AsyncTask se activa desde un ViewTreeObserver.OnGlobalLayoutListener adjunto a MapView.

En el método de la onPostExecute AsyncTask, puedo crear una nueva instancia de mi clase CampsOverlay y pasarlo una lista de los campos devueltos por la base de datos (que son descabellada en doInBackground). entonces yo llamo:

mapView.getOverlays().add(newOverlay); 

donde newOverlay es la CampsOverlay que acaba de crear. Todo este código se ejecuta sin errores, pero cuando el Mapa intenta llamar en sí, consigo una NullPointerException con el seguimiento de pila:

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) 

Porque parece particularmente relevante, aquí está el código para mi ItemizedOverlay subclase:

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(); 
    } 

} 

¿Alguien tiene alguna idea de lo que podría estar pasando aquí? Intenté para verificar que todo lo que tengo control no es nulo. Puedo proporcionar más código si es necesario.

Respuesta

20

No veo a dónde llama populate() en su CampsOverlay.

Here is a sample project mostrando la carga asíncrona de elementos de superposición - quizás le dará algunas ideas, si populate() no es el problema.

+0

Tienes toda la razón, gracias Mark. Pensarías que habría mirado más de cerca tu código de muestra antes de hacer esta pregunta. Ahora solo tengo que averiguar por qué los elementos superpuestos no aparecen;) – lyricsboy

3

Él es correcto. Debe llamar a populate() para rellenar la superposición. Es posible que desee crear todos los elementos de superposición en el constructor, llamar a poblar y en createItem solo devolver el elemento de una lista.

+0

¿Existe alguna ventaja en crear los elementos en el constructor en lugar de uno a la vez dentro de createItem?A partir de mi lectura de la documentación, ItemizedOverlay almacenará en caché los resultados de createItem, por lo que no necesariamente hay que aferrarse a los de mi subclase. – lyricsboy

2

"Ahora sólo tengo que averiguar por qué los elementos de superposición no aparecen"

En caso de que no, es porque usted tiene que utilizar una función estática en su Drawable que explicar cómo es su marcador posicionado

Puede utilizar esta, en su CampsOverlay constructor:

super(boundCenter(defaultMarker));

Esto indicará que el origen de su Drawable es el centro. También puede usar boundCenterBottom() para indicar que el origen está en el centro inferior de Drawable.

Cuestiones relacionadas