在Android中检测OSM Mapview是否仍在加载

8
我已经在我的安卓应用中添加了Open Street Maps。在地图视图中,用户应该能够在地图完全加载后捕捉屏幕。但目前即使在地图视图仍在加载时,用户也能够捕捉图像。有人可以告诉我如何检测地图视图何时完全加载吗?
以下是我的地图视图加载代码:
public class MainActivity extends Activity  {
    MapView mapView;
    MyLocationOverlay myLocationOverlay = null;
    ArrayList<OverlayItem> anotherOverlayItemArray;
    protected ItemizedOverlayWithBubble<ExtendedOverlayItem> itineraryMarkers;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mapView = (MapView) findViewById(R.id.mapview);

        final ArrayList<ExtendedOverlayItem> waypointsItems = new ArrayList<ExtendedOverlayItem>();
        itineraryMarkers = new ItemizedOverlayWithBubble<ExtendedOverlayItem>(this, waypointsItems, mapView, new ViaPointInfoWindow(R.layout.itinerary_bubble, mapView));
        mapView.getOverlays().add(itineraryMarkers);

        mapView.setTileSource(TileSourceFactory.MAPNIK);
        mapView.setBuiltInZoomControls(true);
        MapController mapController = mapView.getController();
        mapController.setZoom(1);
        GeoPoint point2 = new GeoPoint(51496994, -134733);
        mapController.setCenter(point2);

        Drawable marker=getResources().getDrawable(android.R.drawable.star_big_on);
        GeoPoint myPoint1 = new GeoPoint(0*1000000, 0*1000000);
        ExtendedOverlayItem overlayItem = new ExtendedOverlayItem("Title Test Loc", "Desc", myPoint1, this);
        overlayItem.setMarkerHotspot(OverlayItem.HotspotPlace.BOTTOM_CENTER);
        overlayItem.setMarker(marker);
        overlayItem.setRelatedObject(0);
        itineraryMarkers.addItem(overlayItem);
        mapView.invalidate();



        myLocationOverlay = new MyLocationOverlay(this, mapView);
        mapView.getOverlays().add(myLocationOverlay);
        myLocationOverlay.enableMyLocation();

        myLocationOverlay.runOnFirstFix(new Runnable() {
            public void run() {
             mapView.getController().animateTo(myLocationOverlay.getMyLocation());
               } 
           });


    }

    @Override
     protected void onResume() {
      // TODO Auto-generated method stub
      super.onResume();
      myLocationOverlay.enableMyLocation();
      myLocationOverlay.enableCompass();
      myLocationOverlay.enableFollowLocation();
     } 

     @Override
     protected void onPause() {
      // TODO Auto-generated method stub
      super.onPause();
      myLocationOverlay.disableMyLocation();
      myLocationOverlay.disableCompass();
      myLocationOverlay.disableFollowLocation();
     }
4个回答

4
请查看 TilesOverlayTileLooper 实现。这是我们用来加载并在屏幕上绘制每个瓦片的方式。在 handleTile(...) 方法中,我们尝试从瓦片提供者 mTileProvider.getMapTile(pTile) 获取瓦片。如果返回一个 Drawable,则表示瓦片已加载,否则将返回 null
一个简单的方法是扩展 TilesOverlay,重写 drawTiles(...) 方法,并在调用 super.drawTiles(...) 之前调用自己的 TileLooper 来检查传递给 handleTile(...) 的所有瓦片是否都不为 null。要使用您的 TilesOverlay,请调用 mMapView.getOverlayManager().setTilesOverlay(myTilesOverlay)

非常感谢,您能提供一些示例代码吗? - TharakaNirmana
我能够编写出如下的一组代码:public class Tiles extends TilesOverlay{ public Tiles(MapTileProviderBase aTileProvider, Context aContext) { super(aTileProvider, aContext); // TODO Auto-generated constructor stub } @Override public void drawTiles(Canvas c, int zoomLevel, int tileSizePx, Rect viewPort) { // TODO Auto-generated method stub TileLooper tileloop; tileloop.handleTile(arg0, arg1, arg2, arg3, arg4) super.drawTiles(c, zoomLevel, tileSizePx, viewPort); }}请告诉我如何继续。谢谢! - TharakaNirmana

2
自osmdroid API 6.1.0版本开始,这变得非常容易:
// check completeness of map tiles
TileStates tileStates = mapView.getOverlayManager().getTilesOverlay().getTileStates();

// evaluate the tile states
if (tileStates.getTotal() == tileStates.getUpToDate())
{
    // map is loaded completely

}
else
{
    // loading is still in progress

}

/* meaning of TileStates
    .getUpToDate()   not expired yet
    .getExpired()    expired
    .getScaled()     computed during zoom
    .getNotFound()   default grey tile
    ---------------------------------------
    .getTotal()      sum of all above
*/

1
我通过扩展TilesOverlay创建了一个名为"MyTileOverlay"的类,它包含以下内容:

https://code.google.com/p/osmdroid/source/browse/trunk/osmdroid-android/src/main/java/org/osmdroid/views/overlay/TilesOverlay.java?r=1086

然后在设置地图视图时,我这样做:

this.mTilesOverlay = new MyTileOverlay(mProvider, this.getBaseContext());

根据kurtzmarc的指示,我使用handleTile()来检查是否所有的瓷砖都已经加载完成:

@Override
        public void handleTile(final Canvas pCanvas, final int pTileSizePx,
                final MapTile pTile, final int pX, final int pY) {
            Drawable currentMapTile = mTileProvider.getMapTile(pTile);
            if (currentMapTile == null) {
                currentMapTile = getLoadingTile();
                Log.d("Tile Null", "Null");
            } else {

                Log.d("Tile Not Null", "Not Null");
            }

            if (currentMapTile != null) {
                mTileRect.set(pX * pTileSizePx, pY * pTileSizePx, pX
                        * pTileSizePx + pTileSizePx, pY * pTileSizePx
                        + pTileSizePx);
                onTileReadyToDraw(pCanvas, currentMapTile, mTileRect);
            }

            if (DEBUGMODE) {
                mTileRect.set(pX * pTileSizePx, pY * pTileSizePx, pX
                        * pTileSizePx + pTileSizePx, pY * pTileSizePx
                        + pTileSizePx);
                mTileRect.offset(-mWorldSize_2, -mWorldSize_2);
                pCanvas.drawText(pTile.toString(), mTileRect.left + 1,
                        mTileRect.top + mDebugPaint.getTextSize(),
                        mDebugPaint);
                pCanvas.drawLine(mTileRect.left, mTileRect.top,
                        mTileRect.right, mTileRect.top, mDebugPaint);
                pCanvas.drawLine(mTileRect.left, mTileRect.top,
                        mTileRect.left, mTileRect.bottom, mDebugPaint);
            }
        }

这种方法可以确保加载过程是否已完成:

@Override
            public void finaliseLoop() {
                Log.d("Loop Finalized", "Finalized");
            }

我也可以使用这种方法来判断是否已经加载了所有的瓷砖:
public int getLoadingBackgroundColor() {
            return mLoadingBackgroundColor;
        }

希望这能帮助到某些人!

0
您可以将可运行的回调函数传递给瓦片叠加层的TileStates类:
overlayManager.tilesOverlay.tileStates.runAfters.add(Runnable {
        // Tile loading completed
    })

运行得相当不错。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接