【问题标题】:Android Map Overlay IssuesAndroid 地图覆盖问题
【发布时间】:2011-09-22 10:44:36
【问题描述】:

有什么方法可以实现缩放监听器,只要缩放级别发生变化就可以触发事件。到目前为止,我已经使用 onUserinteraction 方法手动检查更改缩放级别。 另一件事是我想要动态添加/删除覆盖。到目前为止,我所做的是在 onUserinteraction 方法中,我调用了一个动态添加叠加层的函数,使用 mapOverlays.add() 函数,并且添加实际上是动态发生的。但不知何故 mapOverlays.remove() 函数并没有删除覆盖

     //Function for adding first set of markers
     public void setOverlay()
{
    worldLength = World.length;
    mapOverlays = mapView.getOverlays();
    drawable0 = this.getResources().getDrawable(R.drawable.marker);
    itemizedOverlay0 = new MyItemizedOverlay(drawable0);
    for (int i = 0; i < worldLength; i++)
    {
        itemizedOverlay0.addOverlay(World[i]);
    }
    mapOverlays.add(itemizedOverlay0);
    mapView.postInvalidate();
}
     //Function for adding second set of markers
     public void setOverlay1() 
     {
      mapView.setStreetView(true);
      usaLength = USA.length;
      mexicoLength = Mexico.length;
               mapOverlays = mapView.getOverlays();
        drawable1 = this.getResources().getDrawable(R.drawable.marker);
        itemizedOverlay1 = new MyItemizedOverlay(drawable1);
        itemizedOverlay2 = new MyItemizedOverlay(drawable1);


        for (int i = 0; i < usaLength; i++) {
            itemizedOverlay1.addOverlay(USA[i]);
        }
        for (int i = 0; i < mexicoLength; i++) {
            itemizedOverlay2.addOverlay(Mexico[i]);
        }

        mapOverlays.add(itemizedOverlay1);
        mapOverlays.add(itemizedOverlay2);


    mapView.postInvalidate();

}

     public void onUserInteraction() {
   super.onUserInteraction();
   if(mapView.getZoomLevel()>3)
   {
       mapOverlays.remove(itemizedOverlay0);
       setOverlay1();
                 //the above happens
   }
   else if(mapView.getZoomLevel()<=3 && mapOverlays.size()>5)
   {
       mapOverlays.remove(itemizedOverlay1);
       mapOverlays.remove(itemizedOverlay2);
                 //the above doesn't
       setOverlay();   
   }
   else if(mapView.getZoomLevel()<=3)
   {

   }
}

【问题讨论】:

    标签: android map overlays


    【解决方案1】:

    为了实现您的自定义缩放处理程序并添加一个侦听器,您需要创建 MapView 的子类。首先,让我们为OnZoomListener 创建接口。请注意,您可以根据需要更改界面,以下只是您开始使用的框架代码

    
    public interface OnZoomListener {
        /***
         * /**
         * Called when there is a zoom changes 
         * @param mapView Reference to the current map view
         * @param currentZoom The current zoom, set to -1 initially
         * @param newZoom The new zoom level
         */
         public void onZoomChanged(MapView mapView, int currentZoom, int newZoom);
    }
    

    现在,您需要一个子类,该子类将在缩放更改时调用此OnZoomListener。这是this SO Answer的扩展的骨架代码

    
    public class MyMapView extends MapView {
        int oldZoomLevel=-1;
        OnZoomListener onZoomListener;
    
        public MyMapView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
        }
    
        public MyMapView(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public MyMapView(Context context, String apiKey) {
            super(context, apiKey);
        }
    
        public void setOnZoomListener(OnZoomListener onZoomListener) {
            this.onZoomListener = onZoomListener;
        }
    
        @Override
        public void dispatchDraw(Canvas canvas) {
            super.dispatchDraw(canvas);
            int newZoom = this.getZoomLevel();
    
            if (newZoom != oldZoomLevel) {
                // dispatch the listeners
                if(oldZoomLevel != -1 &&  onZoomListener != null) {
                    onZoomListener.onZoomChanged(this, oldZoomLevel, newZoom);
                }
    
                // update the new zoom level
                oldZoomLevel = getZoomLevel();
            }
        }
    }
    

    现在您可以在布局中使用MyMapView,而不是标准的MapView。注意:代码包com.so4729255是我用来测试的。

    
      <com.so4729255.MyMapView
                    android:id="@+id/mapview"
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:enabled="true"
                    android:apiKey="YOUR API KEY"
                    android:clickable="true"
            />
    

    最后在您的代码中添加OnZoomListener。下面的代码只是展示了 Toast 的用法,你可以在那里做任何你需要做的事情

    
     MyMapView mapView = (MyMapView)this.findViewById(R.id.mapview);
            mapView.setOnZoomListener(new OnZoomListener() {
                public void onZoomChanged(MapView mapView, int currentZoom,
                        int newZoom) {
                    // implement your handler here
                    Toast t = Toast.makeText(WebViewMain.this, "Zoom has changed from " + currentZoom + " to " + 
                            newZoom, 500);
                    t.show();
                }
            });
    

    至于你的第二个问题,正如每个人都回答的那样,调用MapView.invalidate() 应该用它的新状态重新绘制地图,因为它将强制视图根据the API documentation 重新绘制

    【讨论】:

    • 这很好,一定会尝试回来,我需要尽快知道的是为什么我无法使用 mapOverlays.remove(itemizedOverlayname) 删除;任何即时帮助将不胜感激.....谢谢一百万
    • 您是否尝试过调用 MapView.invalidate() 而不是 mapView.postInvalidate()?根据文档,invalidate() 应该立即重绘地图(至少对于我之前做过的所有地图案例)。
    • 已经完成并且它不起作用,我只是注意到 remove 方法只删除了覆盖对象的第一次出现,但是我的错误代码多次添加了相同的覆盖,因此我看不到结果。将正确解决并回答我自己的问题....顺便说一句,我正在实施您的缩放监听器想法!!!
    【解决方案2】:

    你必须使用刷新地图

    mapview.invalidate()
    

    postInvalidate 在 UI 线程上发布一个无效请求,而 调用 invalidate() 立即使视图无效

    【讨论】:

      【解决方案3】:

      当缩放级别发生变化时,地图会重新绘制,因此我只需将这种类型的功能放在叠加层的绘制方法中,如下所示:

      e@Override
      public void draw(Canvas canvas, MapView mapv, boolean shadow)
      {       
          int zoom = mapv.getZoomLevel();
      
          switch(zoom)
          {
              case 19:
                  setMarkersForZoomLevel19();
                  break;
              case 18:
                  setMarkersForZoomLevel18();
                  break;
              case 17:
                  setMarkersForZoomLevel17();
                  break;
              case 16:
                  setMarkersForZoomLevel16();
                  break;
              default:
                  // Hide the markers or remove the overlay from the map view.                
                  mapv.getOverlays().clear();
          }       
      
          // Putting this call here rather than at the beginning, ensures that
          // the Overlay items are drawn over the top of canvas stuff e.g. route lines.
          super.draw(canvas, mapv, false);        
      }
      

      当你移除一个覆盖层时,记得调用 mapView.invalidate()。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-03-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-28
        相关资源
        最近更新 更多