У меня есть относительно простой MapActivity, что я пытаюсь сделать дисплей списком "лагерей" в данном регионе карты. Я создал пользовательский подкласс OverlayItem по имени CampOverlayItem, пользовательского ItemizedOverlay по имени CampsOverlay, который возвращает CampOverlayItems и конечно подкласс MapActivity, который заполняет карту.
Я вытягиваю данные наложения из базы данных с помощью AsyncTask, как создано в моем действии. AsyncTask инициирован от ViewTreeObserver. OnGlobalLayoutListener присоединил к MapView.
В onPostExecute методе AsyncTask я создаю новый экземпляр своего класса CampsOverlay и передаю его список лагерей, возвращенных из базы данных (которые выбираются в doInBackground). Я затем звоню:
mapView.getOverlays().add(newOverlay);
где newOverlay является CampsOverlay, я просто создал. Весь этот код работает без ошибки, но когда Карта пытается потянуть себя, я получаю NullPointerException со следующим отслеживанием стека:
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)
Поскольку это кажется особенно релевантным, вот код для моего подкласса ItemizedOverlay:
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();
}
}
У кого-либо есть какая-либо идея, что могло происходить здесь? Я попытался проверить, что все, чем я управляю, является непустым. Я могу предоставить больше кода при необходимости.
Я не вижу, куда вы вызываете populate ()
в вашем CampsOverlay
.
Вот пример проекта , демонстрирующего асинхронную загрузку элементов оверлея - возможно, он даст вам некоторые идеи, если populate ()
не является проблемой.
Он прав. Вы должны вызвать populate(), чтобы заполнить оверлей. Вы можете создать все элементы оверлея в конструкторе, вызвать populate, а в createItem просто вернуть элемент из списка.
"Теперь мне осталось выяснить, почему элементы наложения не появляются"
Если вы не знали, то это потому, что вам нужно использовать статическую функцию на вашем Drawable
, которая объяснит, как позиционируется ваш маркер.
Вы можете использовать это в конструкторе CampsOverlay
:
super(boundCenter(defaultMarker));
Это укажет, что начало координат вашего Drawable
является центром. Вы также можете использовать boundCenterBottom()
, чтобы указать, что начало координат - это нижний центр Drawable
.