Проблемы с наложением карты Android
Есть ли способ, которым я могу реализовать слушатель масштабирования, который может запускать события, как только изменяется уровень масштабирования. До сих пор я справился с методом 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)
{
}
}
3 ответа
Чтобы реализовать свой собственный обработчик масштабирования и добавить слушателя, вам нужно создать свой подкласс 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
всякий раз, когда изменяется масштаб. Вот скелетный код для того, что является расширением этого SO Ответа
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
в вашем коде. Код ниже просто показывает тост для иллюстрации использования, вы можете сделать все, что вам нужно сделать там
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()
следует перерисовать карту с ее новым состоянием, так как это заставит View перерисовываться согласно документации API
Когда уровень масштабирования изменяется, карта перерисовывается, поэтому я просто включил этот тип функциональности в метод рисования моего наложения, например так:
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().
Ну вы должны обновить карту с помощью
mapview.invalidate()
postInvalidate публикует недействительный запрос в потоке пользовательского интерфейса, в то время как вызов invalidate() делает аннулирование представления незамедлительным.