mapbox-plugins-android icon indicating copy to clipboard operation
mapbox-plugins-android copied to clipboard

mapView.setOnTouchListener#onTouch is not invoked with Annotations

Open ulusoyca opened this issue 5 years ago • 9 comments

I set onTouchListener for MapView and the code inside the block as below was invoked each time.

  mapView.setOnTouchListener { view, event -> ... }

However, after initializing LineManager, View.OnTouchListener has no effect. What is causing it and how can I fix it?

Platform: Android mapboxAnnotationsVersion = '0.5.0'

ulusoyca avatar Mar 18 '19 12:03 ulusoyca

As a workaround until there is a fix, this ugly trick solves the issue:

  1. Add an empty view on top of MapView
  2. Set the OnTouchListener for that view.

ulusoyca avatar Mar 19 '19 13:03 ulusoyca

LineManager is an implementation of AnnotationManager which uses a DraggableAnnotationController which also sets a touchListener on the mapView.

Unfortunately, you can only set one touchListener on the View (it's a setOnTouchListener, not an addOnTouchListener)

The current conclusion is that you can't do both at the same time. One other workaround would be to add a callback to be called before androidGesturesManager.onTouchEvent(event); is triggered. Another one if you are using the androidGesturesManager would be to have is injected in like it's done in the second constructor currently.

Could you explain your use case?

sebastienrouif avatar Mar 21 '19 12:03 sebastienrouif

Thanks, in my use case I have a Mapview inside a RecyclerView. Based on the touch coordinate point, I set the flag for parent.requestDisallowInterceptTouchEvent().

ulusoyca avatar Mar 21 '19 12:03 ulusoyca

Thanks, in my use case I have a Mapview inside a RecyclerView. Based on the touch coordinate point, I set the flag for parent.requestDisallowInterceptTouchEvent().

You can use your custom Mapview. This mapview extends mapview and override onTouchEvent() Like below in my case: public static class CustomMapView extends MapView {

    public CustomMapView(@NonNull Context context) {
        super(context);
    }

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

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

    public CustomMapView(@NonNull Context context, @Nullable MapboxMapOptions options) {
        super(context, options);
    }

    List<MapTouchListener> mapDownUpListeners = new ArrayList<>();

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        super.onTouchEvent(event);
        if (event.getAction() == KeyEvent.ACTION_DOWN) {
            for (MapTouchListener listener : mapDownUpListeners) {
                listener.onTouchDown();
            }
            return true;
        } else if (event.getAction() == KeyEvent.ACTION_UP) {
            for (MapTouchListener listener : mapDownUpListeners) {
                listener.onTouchUp();
            }
            return true;
        }
        return true;
    }
}

dongzhixuanyuan avatar Apr 08 '19 12:04 dongzhixuanyuan

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Oct 05 '19 12:10 stale[bot]

This issue has been automatically detected as stale because it has not had recent activity and will be archived. Thank you for your contributions.

stale[bot] avatar Oct 05 '19 13:10 stale[bot]

Thanks, in my use case I have a Mapview inside a RecyclerView. Based on the touch coordinate point, I set the flag for parent.requestDisallowInterceptTouchEvent().

You can use your custom Mapview. This mapview extends mapview and override onTouchEvent() Like below in my case: public static class CustomMapView extends MapView {

    public CustomMapView(@NonNull Context context) {
        super(context);
    }

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

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

    public CustomMapView(@NonNull Context context, @Nullable MapboxMapOptions options) {
        super(context, options);
    }

    List<MapTouchListener> mapDownUpListeners = new ArrayList<>();

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        super.onTouchEvent(event);
        if (event.getAction() == KeyEvent.ACTION_DOWN) {
            for (MapTouchListener listener : mapDownUpListeners) {
                listener.onTouchDown();
            }
            return true;
        } else if (event.getAction() == KeyEvent.ACTION_UP) {
            for (MapTouchListener listener : mapDownUpListeners) {
                listener.onTouchUp();
            }
            return true;
        }
        return true;
    }
}

Can someone confirm this works ? Not working for me

ghost avatar Dec 09 '19 11:12 ghost

Getting the same problem. I have my MapView inside a RecyclerView, trying to catch onToucheEvent callback but do not get anything so far. Huge problem as my MapView is not scrollable inside my RecyclerView. Does anyone has a fix for this ?

houdayec avatar Jan 09 '20 16:01 houdayec

I just pushed a PR to fix this issue, see #1157. Hope this will help.

Ph0tonic avatar Dec 29 '20 13:12 Ph0tonic