如何在 Google Map API v2 中处理地图的 onTouch 事件?

Posted

技术标签:

【中文标题】如何在 Google Map API v2 中处理地图的 onTouch 事件?【英文标题】:How to handle onTouch event for map in Google Map API v2? 【发布时间】:2012-11-23 06:10:40 【问题描述】:

默认情况下,GoogleMap 不提供地图拖动开始和拖动停止的事件。 I have already reported that problem here.

我想自定义 handler 将使用普通的onTouch 事件并将其与setOnCameraChangeListener 结合起来。

但是我找不到如何访问 GoogleMap 对象的 onTouch 事件。它不提供这样的回调

我想知道如何在 Google Map API v2 中处理地图的 onTouch 事件?

【问题讨论】:

叠加层呢?他们在 API v2 中还有 onTouchEvent() 回调吗? 不再有覆盖。对于标记和几何对象,他们引入了单独的方法。 为什么不使用 CameraChangeListener? 【参考方案1】:

这是确定拖动开始和拖动结束事件的可能解决方法:

您必须扩展 SupportMapFragmentMapFragment。在onCreateView() 中,您必须将MapView 包装在自定义的FrameLayout 中(在下面的示例中,它是TouchableWrapper 类),您可以在其中拦截触摸事件并识别地图是否被点击。如果您的 onCameraChange 被调用,只需检查地图视图是否被按下(在下面的示例中,这是变量 mMapIsTouched)。

示例代码:

更新1:

getView() 中返回原始创建的视图 使用dispatchTouchEvent() 而不是onInterceptTouchEvent()

自定义框架布局:

private class TouchableWrapper extends FrameLayout 
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) 
    switch (ev.getAction()) 
        case MotionEvent.ACTION_DOWN:
        mMapIsTouched = true;
        break;

    case MotionEvent.ACTION_UP:
        mMapIsTouched = false;
        break;
        

        return super.dispatchTouchEvent(ev);
    
    

在您自定义的 MapFragment 中:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) 
    mOriginalContentView = super.onCreateView(inflater, parent, savedInstanceState);

    mTouchView = new TouchableWrapper(getActivity());
    mTouchView.addView(mOriginalContentView);

    return mTouchView;


@Override
public View getView() 
    return mOriginalContentView;

在你的相机更换回调方法中:

private final OnCameraChangeListener mOnCameraChangeListener = new OnCameraChangeListener() 
    @Override
    public void onCameraChange(CameraPosition cameraPosition) 
        if (!mMapIsTouched) 
            refreshClustering(false);
        
    
;

【讨论】:

嘿@Alexey Zakharov,请查看 Google 地图问题跟踪器中的主题:code.google.com/p/gmaps-api-issues/issues/… @Alexey Zakharov 我试过了,但我得到了错误:第一个错误是在 getActivity 上。你能发布你自定义的 MapFragment 类声明吗? (或整个代码) 您需要扩展 SupportMapFragment 或 MapFragment。 @AZ13,我确实使用了您的解决方案作为基础,但我通过使用自定义侦听器而不是公共静态变量对其进行了改进。请在下面查看我的解决方案。此外,在您的情况下,在 OnCameraChangeListener 中使用 mMapIsTouched 布尔值在大多数情况下都不起作用,因为 OnCameraChangeListener 在更新布尔值之前往往会触发,因此您在 if 中的代码永远不会触发。 @AZ13,很棒的答案。如果您或其他任何人有兴趣,我刚刚创建了一个库,用于管理一个可拖动的覆盖框,使用这个答案作为灵感。在这里找到它:github.com/mattlogan/DraggableOverlayBox【参考方案2】:

有一种更简单的方法可以做到这一点,像这样处理onCameraMoveStarted监听器上的案例

下面的代码sn -p

@Override
public void onCameraMoveStarted(int reason) 
    if (reason == OnCameraMoveStartedListener.REASON_GESTURE) 
        Toast.makeText(this, "The user gestured on the map.",
                       Toast.LENGTH_SHORT).show();
     else if (reason == OnCameraMoveStartedListener
                            .REASON_API_ANIMATION) 
        Toast.makeText(this, "The user tapped something on the map.",
                       Toast.LENGTH_SHORT).show();
     else if (reason == OnCameraMoveStartedListener
                            .REASON_DEVELOPER_ANIMATION) 
        Toast.makeText(this, "The app moved the camera.",
                       Toast.LENGTH_SHORT).show();
    

【讨论】:

以上是关于如何在 Google Map API v2 中处理地图的 onTouch 事件?的主要内容,如果未能解决你的问题,请参考以下文章

Google Map Android API V2 中两个位置之间的旅行时间

使用 Google Map API V2 查找地图上两点之间的距离

地形高度 Google Map Api v2

Google Developer 控制台“Google Map Android API V2”选项未查看启用

Android onLocationChanged with Direction使用Google Map Api v2

在 android 中扩展 google map api v2 的离线矢量 TileProvider