2010-03-31 28 views
14

Tôi có MapActivity tương đối đơn giản mà tôi đang cố gắng hiển thị danh sách các "trại" trong một khu vực bản đồ nhất định. Tôi đã tạo một lớp con tùy chỉnh của Lớp phủ được gọi là CampOverlayItem, một tùy chỉnh ItemizedOverlay được gọi là CampsOverlay trả về CampOverlayItems và tất nhiên là lớp con MapActivity điền vào bản đồ.NullPointerException trong ItemizedOverlay.getIndexToDraw

Tôi đang kéo dữ liệu lớp phủ từ cơ sở dữ liệu bằng cách sử dụng AsyncTask làm được tạo trong hoạt động của mình. AsyncTask được kích hoạt từ ViewTreeObserver.OnGlobalLayoutListener được gắn vào MapView.

Trong phương pháp onPostExecute của AsyncTask, tôi tạo một đối tượng mới của lớp CampsOverlay tôi và vượt qua nó một danh sách các trại trở về từ cơ sở dữ liệu (mà được lấy trong doInBackground). Sau đó tôi gọi:

mapView.getOverlays().add(newOverlay); 

nơi newOverlay là CampsOverlay tôi vừa tạo. Tất cả các mã này chạy mà không có lỗi, nhưng khi Bản đồ cố gắng để vẽ bản thân, tôi nhận được một NullPointerException với stack trace sau:

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) 

Bởi vì nó có vẻ đặc biệt có liên quan, đây là mã cho ItemizedOverlay của tôi subclass:

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

} 

Có ai biết điều gì có thể xảy ra ở đây không? Tôi đã thử để xác minh rằng mọi thứ tôi có quyền kiểm soát đều không phải là không. Tôi có thể cung cấp thêm mã nếu cần.

Trả lời

20

Tôi không thấy nơi bạn đang gọi populate() trên số CampsOverlay của mình.

Here is a sample project hiển thị tải không đồng bộ các mục lớp phủ - có lẽ nó sẽ cung cấp cho bạn một số ý tưởng, nếu populate() không phải là vấn đề.

+0

Bạn hoàn toàn đúng, cảm ơn Mark. Bạn nghĩ rằng tôi sẽ xem xét kỹ hơn mã mẫu của bạn trước khi đặt câu hỏi này. Bây giờ tôi chỉ cần tìm ra lý do tại sao các mục lớp phủ không xuất hiện;) – lyricsboy

3

Anh ấy đúng. Bạn phải gọi populate() để điền vào lớp phủ. Bạn có thể muốn tạo tất cả các mục overlay trong constructor, gọi populate, và trong createItem chỉ trả về item từ danh sách.

+0

Có một lợi thế để tạo các mục trong hàm tạo thay vì một mục trong một thời gian bên trong createItem không?Từ đọc tài liệu của tôi, ItemizedOverlay sẽ lưu trữ kết quả của createItem, vì vậy không nhất thiết phải cần phải treo vào các kết quả trong lớp con của tôi nữa. – lyricsboy

2

"Bây giờ tôi chỉ phải tìm ra lý do tại sao các mục lớp phủ không xuất hiện"

Trong trường hợp bạn không, đó là vì bạn phải sử dụng một hàm tĩnh trên Drawable của bạn mà sẽ giải thích thế nào là của bạn đánh dấu vị trí.

Bạn có thể sử dụng này, trong constructor CampsOverlay của bạn:

super(boundCenter(defaultMarker));

này sẽ chỉ ra rằng nguồn gốc của Drawable của bạn là trung tâm. Bạn cũng có thể sử dụng boundCenterBottom() để cho biết rằng nguồn gốc là trung tâm dưới cùng của Drawable.

Các vấn đề liên quan