谷歌地图Android API v2 - 检测地图上的触摸

Gau*_*cho 70 maps android google-maps touch google-maps-api-2

我无法找到有关如何拦截新版Google Maps API v2上的地图触摸的示例.

我需要知道用户何时触摸地图以停止线程(地图围绕我当前位置的居中).

Gau*_*cho 93

@ape在这里写了一个关于如何拦截地图点击的答案,但我需要拦截触摸,然后他在其答案的注释中建议了以下链接,如何在Google Map API v2中处理地图的onTouch事件?.

该解决方案似乎是一种可能的解决方法,但建议的代码不完整.出于这个原因,我重新编写并测试了它,现在它可以工作了.

这是工作代码:

我创建了MySupportMapFragment.java类

import com.google.android.gms.maps.SupportMapFragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class MySupportMapFragment extends SupportMapFragment {
    public View mOriginalContentView;
    public TouchableWrapper mTouchView;

    @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;
    }
}
Run Code Online (Sandbox Code Playgroud)

我甚至创建了TouchableWrapper.java类:

import android.content.Context;
import android.view.MotionEvent;
import android.widget.FrameLayout;

public class TouchableWrapper extends FrameLayout {

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

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {

        switch (event.getAction()) {

            case MotionEvent.ACTION_DOWN:
                  MainActivity.mMapIsTouched = true;
                  break;

            case MotionEvent.ACTION_UP:
                  MainActivity.mMapIsTouched = false;
                  break;
        }
        return super.dispatchTouchEvent(event);
    }
}
Run Code Online (Sandbox Code Playgroud)

在布局中我以这种方式声明:

<fragment xmlns:android="http://schemas.android.com/apk/res/android"
          android:id="@+id/mapFragment"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:layout_alignParentBottom="true"
          android:layout_below="@+id/buttonBar"
          class="com.myFactory.myApp.MySupportMapFragment"
/>
Run Code Online (Sandbox Code Playgroud)

只是为了在主Activity中测试我只写了以下内容:

public class MainActivity extends FragmentActivity {
    public static boolean mMapIsTouched = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 投票,因为那不是用户需要的,而是他问的。这就是我所需要的:) (2认同)

Sam*_*mar 44

这是一个基于用户选择获取位置的简单解决方案(地图上的点击选项)

googleMap.setOnMapClickListener(new OnMapClickListener() {
  @Override
  public void onMapClick(LatLng arg0) {
    // TODO Auto-generated method stub
    Log.d("arg0", arg0.latitude + "-" + arg0.longitude);
  }
});
Run Code Online (Sandbox Code Playgroud)

  • 如果您单击一个标记,根本不会被调用。 (3认同)
  • 当您平稳地触摸地图时,此过程将起作用,但是当您几乎不触摸地图并开始缩放时,此过程将因此而不会调用onMapClick方法。 (2认同)
  • setOnMapClickListener无法识别。我应该导入什么? (2认同)

A.A*_*omi 27

现在支持此功能和更多功能:)

这是开发者说明(问题4636):

2016年8月发布了一系列用于摄像机动作启动,持续和结束事件的新型摄像机更换监听器.您还可以看到相机移动的原因,无论是由用户手势,内置API动画还是开发人员控制的动作引起的.有关详细信息,请参阅相机更改活动指南:https: //developers.google.com/maps/documentation/android-api/events#camera-change-events

另请参阅发行说明:https: //developers.google.com/maps/documentation/android-api/releases#august_1_2016

这是文档页面中的代码片段

public class MyCameraActivity extends FragmentActivity implements
        OnCameraMoveStartedListener,
        OnCameraMoveListener,
        OnCameraMoveCanceledListener,
        OnCameraIdleListener,
        OnMapReadyCallback {

    private GoogleMap mMap;

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

        SupportMapFragment mapFragment =
            (SupportMapFragment) getSupportFragmentManager()
                    .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);
    }

    @Override
    public void onMapReady(GoogleMap map) {
        mMap = map;

        mMap.setOnCameraIdleListener(this);
        mMap.setOnCameraMoveStartedListener(this);
        mMap.setOnCameraMoveListener(this);
        mMap.setOnCameraMoveCanceledListener(this);

        // Show Sydney on the map.
        mMap.moveCamera(CameraUpdateFactory
                .newLatLngZoom(new LatLng(-33.87365, 151.20689), 10));
    }

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

    @Override
    public void onCameraMove() {
        Toast.makeText(this, "The camera is moving.",
                       Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onCameraMoveCanceled() {
        Toast.makeText(this, "Camera movement canceled.",
                       Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onCameraIdle() {
        Toast.makeText(this, "The camera has stopped moving.",
                       Toast.LENGTH_SHORT).show();
    }
}
Run Code Online (Sandbox Code Playgroud)


Fly*_*iew 9

我在布局中的MapFragment顶部创建了一个空的FrameLayout.然后我在这个视图上设置了一个onTouchListener,所以我知道什么时候触摸了地图但返回false,以便将触摸传递给地图.

<FrameLayout
    android:id="@+id/map_touch_layer"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

mapTouchLayer.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            Utils.logDebug(TAG, "Map touched!");
            timeLastTouched = System.currentTimeMillis();
            return false; // Pass on the touch to the map or shadow layer.
        }
    });
Run Code Online (Sandbox Code Playgroud)


Bjö*_*hel 7

Gaucho有一个很好的答案,看到我认为可能需要另外一个实现的许多upvotes:

我需要它来使用一个监听器,所以我可以在触摸时作出反应,而不必经常检查它.

我将所有内容放在一个可以像这样使用的类中:

mapFragment.setNonConsumingTouchListener(new TouchSupportMapFragment.NonConsumingTouchListener() {
    @Override
    public void onTouch(MotionEvent motionEvent) {
        switch (motionEvent.getActionMasked()) {
            case MotionEvent.ACTION_DOWN:
                // map is touched
                break;
            case MotionEvent.ACTION_UP:
                // map touch ended
                break;
            default:
                break;
            // use more cases if needed, for example MotionEvent.ACTION_MOVE
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

其中mapfragment需要是TouchSupportMapFragment类型,并且在布局xml中需要这一行:

<fragment class="de.bjornson.maps.TouchSupportMapFragment"
...
Run Code Online (Sandbox Code Playgroud)

这是班级:

package de.bjornson.maps;

import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;

import com.google.android.gms.maps.SupportMapFragment;

public class TouchSupportMapFragment extends SupportMapFragment {
    public View mOriginalContentView;
    public TouchableWrapper mTouchView;
    private NonConsumingTouchListener mListener;

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

    public void setNonConsumingTouchListener(NonConsumingTouchListener listener) {
        mListener = listener;
    }

    public interface NonConsumingTouchListener {
        boolean onTouch(MotionEvent motionEvent);
    }

    public class TouchableWrapper extends FrameLayout {

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

        @Override
        public boolean dispatchTouchEvent(MotionEvent event) {
            if (mListener != null) {
                mListener.onTouch(event);
            }
            return super.dispatchTouchEvent(event);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


ada*_*rsh 6

https://developers.google.com/maps/documentation/android/reference/com/google/android/gms/maps/GoogleMap.OnMapClickListener

看到这个链接.实现接口并填写onMapClick() 方法或任何您需要的方法,并设置onMapClickListener正确的实现.

public class YourActivity extends Activity implements OnMapClickListener {
    @Override
    protected void onCreate(Bundle icicle) { 
        super.onCreate(icicle);
        ...
        my_map.setOnMapClickListener(this)        
        ...
    }

    public void onMapClick (LatLng point) {
        // Do Something
    }
}
Run Code Online (Sandbox Code Playgroud)

  • Map Touch不是“点击地图”,因此无法回答问题。由于用户触摸地图,我需要拦截地图移动,而我无法找到一种有效的方法来拦截此操作。我认为我无法使用setOnCameraChangeListener,因为我仍然使用animateCamera方法来更新代码中的摄像头位置,然后我只需要一个侦听器即可在平移地图期间拦截对地图的触摸。 (2认同)
  • 好吧,我想这有帮助吗?http://stackoverflow.com/questions/13722869/how-to-handle-ontouch-event-for-map-in-google-map-api-v2 (2认同)