Intercept Android Google Maps Touch and Click

Aug 15, 2017

I want to intercept all click and touch on Google Maps fragment.

For my use case, I have a small map fragment in my activity. Once user click or touch or drag or pinch on the map fragment, it will launch an activity with a fullscreen map.

GoogleMap listeners

The easiest method is to utilize GoogleMap's listeners:

  • setOnMapClickListener - the map is clicked (will not trigger if marker is clicked)
  • setOnMarkerClickListener - the marker is clicked
  • setOnCameraMoveStartedListener - touch, drag or pinch event (scroll and zoom)
mapFragment.getMapAsync(new OnMapReadyCallback() {    @Override    public void onMapReady(final GoogleMap map) {        map.setOnMapClickListener(new GoogleMap.OnMapClickListener() {            @Override            public void onMapClick(LatLng latLng) {                Log.d(TAG, "onMapClick");                startMap();            }        });        map.setOnCameraMoveStartedListener(new GoogleMap.OnCameraMoveStartedListener() {            @Override            public void onCameraMoveStarted(int reason) {                if (reason == GoogleMap.OnCameraMoveStartedListener.REASON_GESTURE) {                    Log.d(TAG, "onCameraMoveStarted");                    startMap();                }            }        });        map.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {            @Override            public boolean onMarkerClick(Marker marker) {                Log.d(TAG, "onMarkerClick");                startMap();                return true;            }        });    }});    

I want the map to remain static, where it cannot be scrolled or zoomed by the user. The above listeners doesn't prevent that.

I can use map.getUiSettings().setAllGesturesEnabled(false) to disable gestures and make the map static. The problem is that only the click listener are triggered, where nothing happens if user touch, drag or pinch the map. I want to receive an event when user touch, drag or pinch the map.

// disable all gestures, OnCameraMoveStartedListener will not be triggeredmap.getUiSettings().setAllGesturesEnabled(false);

Extend SupportMapFragment with TouchableWrapper

To intercept all click and touch events and prevent the events from being replayed to Google Maps, we need extend SupportMapFragment.

We add a FrameLayout as an overlay on map view, overriding dispatchTouchEvent and consume all MotionEvent.ACTION_DOWN events.

public class StaticMapFragment extends SupportMapFragment {    public View mapView;    public TouchableWrapper touchView;    private StaticMapFragment.OnTouchListener listener;    public static StaticMapFragment newInstance() {        return new StaticMapFragment();    }    @Override    public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {        mapView = super.onCreateView(inflater, parent, savedInstanceState);        // overlay a touch view on map view to intercept the event        touchView = new TouchableWrapper(getActivity());        touchView.addView(mapView);        return touchView;    }    @Override    public View getView() {        return mapView;    }    public void setOnTouchListener(StaticMapFragment.OnTouchListener listener) {        this.listener = listener;    }    public interface OnTouchListener {        void onTouch();    }    public class TouchableWrapper extends FrameLayout {        public TouchableWrapper(Context context) {            super(context);        }        @Override        public boolean dispatchTouchEvent(MotionEvent event) {            switch (event.getAction()) {                case MotionEvent.ACTION_DOWN:                    if (listener != null) {                        listener.onTouch();                    }                    // consume event to prevent map from receiving the event                    return true;            }            return super.dispatchTouchEvent(event);        }    }}

Usage.

mapFragment.setOnTouchListener(new StaticMapFragment.OnTouchListener() {    @Override    public void onTouch() {        Log.d(TAG, "onTouch");        startMap();    }});

References

❤️ Is this article helpful?

Buy me a coffee ☕ or support my work via PayPal to keep this space 🖖 and ad-free.

Do send some 💖 to @d_luaz or share this article.

✨ By Desmond Lua

A dream boy who enjoys making apps, travelling and making youtube videos. Follow me on @d_luaz

👶 Apps I built

Travelopy - discover travel places in Malaysia, Singapore, Taiwan, Japan.