web-dev-qa-db-ja.com

android上のGoogleマップのズームイベント

Android用のgoogle maps apiを使用するアプリケーションを作成しています。

私は自分のMapControllerとMapViewを持っており、以下を使用して組み込みのズームコントロールを有効にします。

mapView.setBuiltInZoomControls(true);

ユーザーが実際に地図をズームしたときにイベントを取得したいのですが、どうすればよいですか?そのようなイベントや、ズームレベルの変化を検出できる一般的なイベントは見つかりません。

更新

mapView.getZoomControls()は非推奨です 。また、ドキュメントでは代わりにmapView.setBuiltInZoomControls(bool)を使用することを推奨しています。これは問題ありませんが、組み込みのズームコントロールからイベントを操作する方法がわかりません。

41

Googleマップ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
        }
    }
});
40
tarmelop

Android Handler を使用して、ズームが変更されたことを検出するために、ズーム値の独自の基本的な「ポーリング」を実装できます。

実行可能なイベントに次のコードを使用します。ここで、処理を行う必要があります。

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

Startコールバックイベントを使用して

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

stopアクティビティを終了するときに

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

記事これに基づいています here もっと長く書きたい場合は、.

25
Kurru

私はonZoom関数リスナーを持つこのライブラリを使用しています。 http://code.google.com/p/mapview-overlay-manager/ 。うまくいきます。

7
Abhinav

OPが言ったように、onUserInteractionEventを使用してテストを自分で行います。

5
Billy Bob Bain

これがクリーンなソリューションです。この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
        }
5
Damian

使用できます

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

それが役に立てば幸い

4
Felipe Conde

Android API は、setOnZoomInClickListener()がある ZoomControls を使用することをお勧めします

これらのズームコントロールを追加するには、次のようにします。

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

そして、mZoomをレイアウトに追加します。

4
JasonOfEarth

この質問には別の答えがあると思います。 Overlayクラスのdrawメソッドはズーム後に呼び出され、ズームレベルが変更された後に呼び出されると思います。これを利用するようにアプリを設計できませんか?必要に応じて、これを検出するためだけにダミーオーバーレイを使用することもできます。これは、遅延のあるランナブルを使用するよりも効率的ではないでしょうか?

@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);
}
3
Paul

V2.0より前のバージョンでは、マップ領域が変更を開始(onRegionBeginChange)し、変更を停止(onRegionEndChange)したときにリスナーにイベントを通知するMapViewを拡張するクラスを作成しました。

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);
    }
}
2
David

Uは、このようなズームCControlを持つことができます。

ここでは、ズームコントロールを実装する方法をコードに添付しています。

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

..これは私が実装した方法です...

ありがとう..Rakesh

2

上記の混合物を使用しました。ティマーを使用して0.5秒ごとにスレッドを開始すると、マップが非常にぎこちなくなることがわかりました。おそらく、毎回いくつかのIfステートメントを使用していたからでしょう。そのため、onUserInteractionから500msのポスト遅延でスレッドを開始しました。これにより、スレッドが実行を開始する前にzoomLevelが更新されるのに十分な時間が与えられるため、500ミリ秒ごとにスレッドを実行しなくても正しいズームレベルを取得できます。

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