如何在GoogleMap Android中检测onDoubleTap缩放 [英] How to detect onDoubleTap zoom in googleMap android

查看:78
本文介绍了如何在GoogleMap Android中检测onDoubleTap缩放的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试检测anroid中googleMap上的onDoubleTap缩放(仅缩放既不滚动也不旋转/倾斜).实际上,我想要实现uber所使用的缩放概念,例如,如果您双击地图,则标记为就像缩放地图之前的位置一样稳定,我的意思是无论缩放级别是多少,坐标都应该相同.例如,如果我双击地图上的任何位置,都应始终放大到mapView的中心.

I am trying to detect the onDoubleTap zoom on googleMap in anroid (only zoom neither scroll nor rotate/tilt).Actually I want to achieve that zooming concept which is used by uber like if you double tap on map the marker is as stable as it was on the location before zoom on the map, I mean the coordinates should be the same no matter what is the zooming level.For example if I double tap anywhere on map it should always zoom in to the center of the mapView.

推荐答案

您可以在答案中修改public boolean dispatchTouchEvent(MotionEvent event)对于您先前的问题,例如,检测两次敲击在第一次敲击和第二次敲击之间的延迟,例如:

You can modify public boolean dispatchTouchEvent(MotionEvent event) in that answer for your previous question for detect double taps on delays between first and second taps, for example that way:

public class TouchableWrapper extends FrameLayout {

    private GoogleMap mGoogleMap = null;
    private long mLastTouchTime = -1;      // time of first tap

    public TouchableWrapper(Context context) {
        super(context);
    }

    public void setGoogleMap(GoogleMap googleMap) {
        mGoogleMap = googleMap;
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {

        switch (event.getAction() & MotionEvent.ACTION_MASK) {

            case MotionEvent.ACTION_DOWN:
                mGoogleMap.getUiSettings().setScrollGesturesEnabled(true);

                long thisTime = System.currentTimeMillis();  // time of second tap tap
                if (thisTime - mLastTouchTime < ViewConfiguration.getDoubleTapTimeout()) {
                    // double tap detected! do you magic here:
                    if (mGoogleMap != null) {
                        LatLng zoomCenter = mGoogleMap.getProjection().fromScreenLocation(new Point((int)event.getX(), (int)event.getY()));
                                                    mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(zoomCenter, currentZoom + 1));
                    }
                    mLastTouchTime = -1;
                } else {
                    mLastTouchTime = thisTime;
                    mGoogleMap.getUiSettings().setZoomGesturesEnabled(true);
                }

            break;

            case MotionEvent.ACTION_POINTER_DOWN:
                mGoogleMap.getUiSettings().setScrollGesturesEnabled(false);
            break;

            case MotionEvent.ACTION_POINTER_UP:
                mGoogleMap.getUiSettings().setScrollGesturesEnabled(true);
            break;

            case MotionEvent.ACTION_UP:
                mGoogleMap.getUiSettings().setScrollGesturesEnabled(true);
            break;
        }

        return super.dispatchTouchEvent(event);
    }
}

更新:

如果使用MapView而不是MapFregment-更好的方法是创建自定义视图,该视图扩展了MapView实现OnMapReadyCallback(对于获取GoogleMap对象是必需的),并覆盖dispatchTouchEvent()(对于双击检测).像这样的东西:

If you use MapView instead of MapFregment - better way is to create custom view, which extends MapView implements OnMapReadyCallback (it's neccessary for get GoogleMap object), and overrides dispatchTouchEvent() (for double tap detection). Something like that:

public class EnhanchedMapView extends MapView implements OnMapReadyCallback {
    private long mLastTouchTime = -1;

    private OnMapReadyCallback mMapReadyCallback;
    private GoogleMap mGoogleMap;
    private Marker mMarker;
    private Paint mPaintArrow;

    public EnhanchedMapView(@NonNull Context context) {
        super(context);
        init();
    }

    public EnhanchedMapView(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public EnhanchedMapView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    public EnhanchedMapView(@NonNull Context context, @Nullable GoogleMapOptions options) {
        super(context, options);
        init();
    }

    private void init() {
    }

    @Override
    public void getMapAsync(OnMapReadyCallback callback) {
        mMapReadyCallback = callback;
        super.getMapAsync(this);
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        mGoogleMap = googleMap;
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {

        switch (event.getAction() & MotionEvent.ACTION_MASK) {

            case MotionEvent.ACTION_DOWN:
                mGoogleMap.getUiSettings().setScrollGesturesEnabled(true);

                long thisTime = System.currentTimeMillis();
                if (thisTime - mLastTouchTime < ViewConfiguration.getDoubleTapTimeout()) {

                    if (mGoogleMap != null) {
                        LatLng zoomCenter = mGoogleMap.getProjection().fromScreenLocation(new Point((int) event.getX(), (int) event.getY()));
                        float currentZoom = mGoogleMap.getCameraPosition().zoom;
                        mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(zoomCenter, currentZoom + 1));
                    }
                    mLastTouchTime = -1;
                } else {
                    mLastTouchTime = thisTime;
                    mGoogleMap.getUiSettings().setZoomGesturesEnabled(true);
                }

                break;

            case MotionEvent.ACTION_POINTER_DOWN:
                mGoogleMap.getUiSettings().setScrollGesturesEnabled(false);
                break;

            case MotionEvent.ACTION_POINTER_UP:
                mGoogleMap.getUiSettings().setScrollGesturesEnabled(true);
                break;

            case MotionEvent.ACTION_UP:
                mGoogleMap.getUiSettings().setScrollGesturesEnabled(true);
                break;
        }

        return super.dispatchTouchEvent(event);
    }
}

更新#2:

活动(MainActivity)的活动布局可能类似于:

Activity layout for activity (MainActivity) that case can be like:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="{YOUR_PACKAGE}.MainActivity">

    <{YOUR_PACKAGE}.EnhanchedMapView
        android:id="@+id/mapview"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        />

</RelativeLayout>

只有MainActivity源代码中的更改是:

And only changes in MainActivity source code is:

...
private EnhanchedMapView mMapView;
...

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    ...
    mMapView = (EnhanchedMapView) findViewById(R.id.mapview);
    ...
}

更新#3:

public class EnhanchedMapView extends MapView implements OnMapReadyCallback {
    private long mLastTouchTime = -1;

    private OnMapReadyCallback mMapReadyCallback;
    private GoogleMap mGoogleMap;

    private LatLng mZoomCenter;

    public EnhanchedMapView(@NonNull Context context) {
        super(context);
        init();
    }

    public EnhanchedMapView(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public EnhanchedMapView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    public EnhanchedMapView(@NonNull Context context, @Nullable GoogleMapOptions options) {
        super(context, options);
        init();
    }

    private void init() {
    }

    @Override
    public void getMapAsync(OnMapReadyCallback callback) {
        mMapReadyCallback = callback;
        super.getMapAsync(this);
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        mGoogleMap = googleMap;
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {

        switch (event.getAction() & MotionEvent.ACTION_MASK) {

            case MotionEvent.ACTION_DOWN:
                mGoogleMap.getUiSettings().setScrollGesturesEnabled(true);
                mGoogleMap.getUiSettings().setZoomGesturesEnabled(false);

                mZoomCenter = mGoogleMap.getCameraPosition().target;

                long thisTime = System.currentTimeMillis();
                if (thisTime - mLastTouchTime < ViewConfiguration.getDoubleTapTimeout()) {

                    if (mGoogleMap != null) {
                        LatLng zoomCenter = mGoogleMap.getProjection().fromScreenLocation(new Point((int) event.getX(), (int) event.getY()));
                        float currentZoom = mGoogleMap.getCameraPosition().zoom;
                        mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(mZoomCenter, currentZoom + 1));
                    }
                    mLastTouchTime = -1;
                } else {
                    mLastTouchTime = thisTime;
                    mGoogleMap.getUiSettings().setZoomGesturesEnabled(true);
                }

                break;

            case MotionEvent.ACTION_POINTER_DOWN:
                mGoogleMap.getUiSettings().setScrollGesturesEnabled(false);
                break;

            case MotionEvent.ACTION_POINTER_UP:
                mGoogleMap.getUiSettings().setScrollGesturesEnabled(true);
                break;

            case MotionEvent.ACTION_UP:
                mGoogleMap.getUiSettings().setScrollGesturesEnabled(true);
                break;
        }

        return super.dispatchTouchEvent(event);
    }
}

这篇关于如何在GoogleMap Android中检测onDoubleTap缩放的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆