是否可以使用 Maps v2 的默认 ZoomControls 来 zoomIn/Out 自定义数量的 ZoomLevel,例如 0.5x?

Is it possible to use default ZoomControls of Maps v2 to zoomIn/Out a custom amount of ZoomLevel such as 0.5x?

我有一个像这样的 mapFragment

   <fragment xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/map"
        android:name="com.google.android.gms.maps.SupportMapFragment"
        android:layout_width="match_parent"
        android:layout_height="0px"
        android:layout_weight="5"
        tools:context="com....."/> 

然后我启用默认的 ZoomControle(“+”和“-”按钮):

public void onMapReady(GoogleMap googleMap){
    googleMap.getUiSettings().setZoomControlsEnabled(true);
    ...
}

使用这些 ZoomControls 使用户能够缩放 in/out 1 个 Zoomlevel。使用 ZoomGestures,用户可以缩放 in/out "continuosly" 即缩放级别之间的值。我可以更改地图 ZoomControls 的缩放 in/out 行为以及不同数量的 ZoomLevel 而不是“1”,例如 0.5 吗?

好的.. 答案是:是的! 以下是我如何将 ZoomControls 的行为更改为按住 + 单击事件并在按下时缩小 in/Zooming 并同时更新 UI(地图)。这种方法还让我可以轻松地为 mapFragment 设置 MaxZoom 和 MinZoom Level,并且比在 OnCameraChangeListener 中设置 ZoomLevel 更好的用户体验!

我已经为 mapFragment 中的那些“+”和“-”子项设置了 OnTouchListener。当手指用 "MotionEvent.ACTION_DOWN" 触摸按钮时,将启动一个用于缩放 in/out 地图的线程。在 "MotionEvent.ACTION_UP",线程被中断:

    mapFragment = (SupportMapFragment) getSupportFragmentManager()
            .findFragmentById(R.id.map);
    mapFragment.getMapAsync(this);
    // get the default ZoomControls from the mapFragment:
    View zoomControls = mapFragment.getView().findViewById(0x1);

    for(int i=0;i<((ViewGroup)zoomControls).getChildCount();i++){
        View child=((ViewGroup)zoomControls).getChildAt(i);
        if (i==0) {
            // there is your "+" button, zoom in
            child.setOnTouchListener(new View.OnTouchListener(){
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    switch (event.getAction()){
                        case MotionEvent.ACTION_DOWN:
                            updateZoom = new ZoomInMapThread();
                            updateZoom.start();
                            break;
                        case MotionEvent.ACTION_UP:
                            updateZoom.interrupt();
                            break;
                    }
                    return true;
                }
            });
        }
        if (i==1) {
            // there is your "-" button, zoom out
            child.setOnTouchListener(new View.OnTouchListener(){
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    switch (event.getAction()){
                        case MotionEvent.ACTION_DOWN:
                            updateZoom = new ZoomOutMapThread();
                            updateZoom.start();
                            break;
                        case MotionEvent.ACTION_UP:
                            updateZoom.interrupt();
                            break;
                    }
                    return true;
                }
            });
        }
    }

在 Activity class 末尾的某处,我创建了 ZoomThreads:

private class ZoomOutMapThread extends Thread {
    @Override
    public void run(){
        try {
            while (!Thread.currentThread().isInterrupted()){
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        currentZoomLevel = currentZoomLevel - 0.1f;
                        if (currentZoomLevel < minZoom){
                            currentZoomLevel = minZoom;
                        }
                        mMap.animateCamera(CameraUpdateFactory.zoomTo(currentZoomLevel));
                        Log.d("Zoom", "Level:" + currentZoomLevel);
                    }
                });
                Thread.sleep(100);
            }
        } catch (InterruptedException consumed) {
            consumed.printStackTrace();
        }
    }
}

private class ZoomInMapThread extends Thread {
    @Override
    public void run(){
        try {
            while (!Thread.currentThread().isInterrupted()){
                // make the Thread able to update the UserInterace:
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        // increase the currentZoomLevel by 0.1:
                        currentZoomLevel = currentZoomLevel + 0.1f;
                        // increase only while we have not reached predefined maxZoom:
                        if (currentZoomLevel > maxZoom){
                            currentZoomLevel = maxZoom;
                            // good moment to disable the "+" button somehow
                        }
                        // update the Camera in GoogleMap mMap from onMapReady():  mMap.animateCamera(CameraUpdateFactory.zoomTo(currentZoomLevel));
                        Log.d("Zoom","Level:"+currentZoomLevel);
                    }
                });
                // repeat every 100ms while finger holds the "+"-Button
                Thread.sleep(100);
            }
        } catch (InterruptedException consumed) {
            consumed.printStackTrace();
        }
    }
}

不要忘记声明 class 个变量:

private float maxZoom = 9.99f;
private float minZoom = 8.2f;
private float currentZoomLevel = 9.1f;

以及 onMapReady(GoogleMap ..):

public void onMapReady(GoogleMap googleMap) {
    mMap = googleMap;

    mMap.getUiSettings().setRotateGesturesEnabled(false);   // prevent rotation UI
    mMap.getUiSettings().setMapToolbarEnabled(false);       // prevent navigate to UI
    mMap.getUiSettings().setZoomGesturesEnabled(false);     // prevent default Zoom Gestures
    mMap.getUiSettings().setZoomControlsEnabled(true);      // show default Zoom Controls (+/-)