О событии масштабирования для Google maps на android

мы создаем приложение, которое использует Google maps api для android.

У меня есть MapController и MapView, и я включаю встроенные элементы управления масштабированием, используя:

mapView.setBuiltInZoomControls(true);

теперь я хотел бы получить событие, когда пользователь действительно приближается к карте, как мне это сделать? Я не могу найти такого события или любого общего события, где я мог бы обнаружить изменение уровня масштабирования.

обновление

в mapView.getZoomControls () устарел. И документации, предполагает, использующие MapView.вместо этого setBuiltInZoomControls (bool). Это нормально, но я просто не могу понять, как действовать на события из встроенных элементов управления масштабированием.

11 ответов


С Google Maps Android API v2 вы можете использовать GoogleMap.OnCameraChangeListener такой:

mMap.setOnCameraChangeListener(new OnCameraChangeListener() {

    private float currentZoom = -1;

    @Override
    public void onCameraChange(CameraPosition pos) {
        if (pos.zoom != currentZoom){
            currentZoom = pos.zoom;
            // do you action here
        }
    }
});

вы можете реализовать свой собственный базовый "опрос" значения масштабирования, чтобы определить, когда масштаб был изменен с помощью android проводник.

использовать следующий код для выполнимое событие. Здесь должна быть сделана обработка.

private Handler handler = new Handler();

public static final int zoomCheckingDelay = 500; // in ms

private Runnable zoomChecker = new Runnable()
{
    public void run()
    {
        checkMapIcons();

        handler.removeCallbacks(zoomChecker); // remove the old callback
        handler.postDelayed(zoomChecker, zoomCheckingDelay); // register a new one
    }
};

старт событие обратного вызова с помощью

protected void onResume()
{
    super.onResume();
    handler.postDelayed(zoomChecker, zoomCheckingDelay);
}

и остановка это, когда вы покидаете деятельность используя

protected void onPause()
{
    super.onPause();
    handler.removeCallbacks(zoomChecker); // stop the map from updating
}

статьи это основано на can be found здесь если вы хотите больше писать.


Я использую эту библиотеку, которая имеет прослушиватель функций onZoom. http://code.google.com/p/mapview-overlay-manager/. Хорошо работает.


Как сказал OP, используйте onUserInteractionEvent и выполните тест самостоятельно.


на API для Андроид предлагает вам использовать ZoomControls, который имеет setOnZoomInClickListener()

чтобы добавить эти элементы управления зумом вы:

ZoomControls mZoom = (ZoomControls) mapView.getZoomControls();

а затем добавьте mZoom в свой макет.


вот это правильное решение. Просто добавьте этот частный класс TouchOverlay в свою активность и метод onZoom (который вызывается этим внутренним классом).

обратите внимание, вам нужно добавить этот TouchOverlay в свой mapView, например

mapView.getOverlays().add(new TouchOverlay());

он отслеживает уровень масштабирования всякий раз, когда пользователь прикасается к карте, например, чтобы дважды нажать или ущипнуть масштабирование, а затем запускает метод onZoom (с уровнем масштабирования), если уровень масштабирования изменяется.

   private class TouchOverlay extends com.google.android.maps.Overlay {
            int lastZoomLevel = -1;

            @Override
            public boolean onTouchEvent(MotionEvent event, MapView mapview) {
                if (event.getAction() == 1) {
                    if (lastZoomLevel == -1)
                        lastZoomLevel = mapView.getZoomLevel();

                    if (mapView.getZoomLevel() != lastZoomLevel) {
                        onZoom(mapView.getZoomLevel());
                        lastZoomLevel = mapView.getZoomLevel();
                    }
                }
                return false;
            }
        }

        public void onZoom(int level) {
            reloadMapData(); //act on zoom level change event here
        }

можно использовать

ZoomButtonsController zoomButton = mapView.getZoomButtonsController();
zoomButton.setOnZoomListener(listener);

надеюсь, что это помогает


Я думаю, что на этот вопрос может быть другой ответ. Метод рисования класса Overlay вызывается после любого масштабирования, и я считаю, что это вызывается после изменения уровня масштабирования. Не могли бы вы создать свое приложение, чтобы воспользоваться этим? Вы даже можете использовать фиктивный оверлей, чтобы обнаружить это, если хотите. Не будет ли это более эффективным, чем использование runnable с задержкой?

@Override
public boolean draw (Canvas canvas, MapView mapView, boolean shadow, long when) {
    int zoomLevel = mapView.getZoomLevel();
    // do what you want with the zoom level
    return super.draw(canvas, mapView, shadow, when);
}

U может иметь масштабирование CControl, как это.

здесь я прикрепляю код, как u может реализовать zoomcontrol.

1>> XML-файл должен быть таким.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent">

    <com.google.android.maps.MapView 
        android:id="@+id/mapView"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:enabled="true"
        android:clickable="true"
        android:apiKey="0l4sCTTyRmXTNo7k8DREHvEaLar2UmHGwnhZVHQ"
        />

    <LinearLayout android:id="@+id/zoom" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:layout_alignParentBottom="true" 
        android:layout_centerHorizontal="true" 
        /> 

</RelativeLayout>

2>> на вас основная деятельность внутри метода oncreate делает следующие вещи. здесь вы раздуваете свой вид с помощью mapView

mapView = (MapView) findViewById(R.id.mapView);
        LinearLayout zoomLayout = (LinearLayout)findViewById(R.id.zoom);  
        View zoomView = mapView.getZoomControls(); 

        zoomLayout.addView(zoomView, 
            new LinearLayout.LayoutParams(
                LayoutParams.WRAP_CONTENT, 
                LayoutParams.WRAP_CONTENT)); 
        mapView.displayZoomControls(true);

........................................................... Вот как вы можете использовать встроенный контроль масштабирования API..

вы можете иметь свой собственный пользовательский код для реализации увеличения и уменьшения масштаба, как это...

public boolean onKeyDown(int keyCode, KeyEvent event) 
{
    MapController mc = mapView.getController(); 
    switch (keyCode) 
    {
        case KeyEvent.KEYCODE_3:
            mc.zoomIn();
            break;
        case KeyEvent.KEYCODE_1:
            mc.zoomOut();
            break;
    }
    return super.onKeyDown(keyCode, event);
}    

..Вот как я реализовал...

спасибо..Ракеш!--4-->


для pre-V2.0, я сделал класс, который расширяет MapView, который предупреждает слушателя о событиях, когда область карты начинает меняться (onRegionBeginChange) и перестает меняться (onRegionEndChange).

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapView;

public class ExMapView extends MapView {
    private static final String TAG = ExMapView.class.getSimpleName();
    private static final int DURATION_DEFAULT = 700;

    private OnRegionChangedListener onRegionChangedListener;
    private GeoPoint previousMapCenter;
    private int previousZoomLevel;
    private int changeDuration; // This is the duration between when the user stops moving the map around and when the onRegionEndChange event fires.
    private boolean isTouched = false;
    private boolean regionChanging = false;

    private Runnable onRegionEndChangeTask = new Runnable() {
        public void run() {
            regionChanging = false;
            previousMapCenter = getMapCenter();
            previousZoomLevel = getZoomLevel();
            if (onRegionChangedListener != null) {
                onRegionChangedListener.onRegionEndChange(ExMapView.this, previousMapCenter, previousZoomLevel);
            }
        }
    };

    public ExMapView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public ExMapView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    public ExMapView(Context context, String apiKey) {
        super(context, apiKey);
        init();
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        isTouched = event.getAction() != MotionEvent.ACTION_UP;
        return super.onTouchEvent(event);
    }

    @Override
    public void computeScroll() {
        super.computeScroll();

        // If the map region is still changing (user is still scrolling or zooming), reset timer for onRegionEndChange.
        if ((!isTouched && !getMapCenter().equals(previousMapCenter)) || (previousZoomLevel != getZoomLevel())) {

            // If the region has just begun changing, fire off onRegionBeginChange event.
            if (!regionChanging) {
                regionChanging = true;
                if (onRegionChangedListener != null) {
                    onRegionChangedListener.onRegionBeginChange(this, previousMapCenter, previousZoomLevel);
                }
            }

            // Reset timer for onRegionEndChange.
            removeCallbacks(onRegionEndChangeTask);
            postDelayed(onRegionEndChangeTask, changeDuration);
        }
    }

    private void init() {
        changeDuration = DURATION_DEFAULT;
        previousMapCenter = getMapCenter();
        previousZoomLevel = getZoomLevel();
    }

    public void setOnRegionChangedListener(OnRegionChangedListener listener) {
        onRegionChangedListener = listener;
    }

    public void setChangeDuration(int duration) {
        changeDuration = duration;
    }

    public interface OnRegionChangedListener {
        public abstract void onRegionBeginChange(ExMapView exMapView, GeoPoint geoPoint, int zoomLevel);
        public abstract void onRegionEndChange(ExMapView exMapView, GeoPoint geoPoint, int zoomLevel);
    }
}

я использовал смесь выше. Я обнаружил, что использование Тиммера для запуска потока каждые полсекунды заставляет карту быть действительно Дженки. Наверное, потому, что я был через пару если заявления каждый раз. Поэтому я начал поток с задержки post 500ms от onUserInteraction. Это дает достаточно времени для zoomlevel для обновления, прежде чем поток начнет работать, таким образом, получая правильный zoomlevel без запуска потока каждые 500 мс.

public void onUserInteraction() {
    handler.postDelayed(zoomChecker, zoomCheckingDelay);
}