Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Detecting complete end of motion on Android in 5.0.0 #8515

Closed
Jukurrpa opened this issue Mar 23, 2017 · 7 comments
Closed

Detecting complete end of motion on Android in 5.0.0 #8515

Jukurrpa opened this issue Mar 23, 2017 · 7 comments
Labels
Android Mapbox Maps SDK for Android

Comments

@Jukurrpa
Copy link

Platform: Android
Mapbox SDK version: 5.0.0

I'd like to detect complete end of motion of the camera on the Android SDK (no camera movement, no user interaction). For this I've tried combining several things such as OnMapChangedListener with different states, OnCameraChangeListener, OnScrollListener, OnFlingListener as well as an OnTouchListener.

On v4.2.2 I managed to get something that somewhat does the job with just OnMapChangedListener and OnTouchListener as I described in this stackoverflow question. Basically the remaining issue was that the chaining of events implies there is a complete stop when the user stops touching the screen and the fling inertia kicks in:

[Touch begins]
03-23 15:51:15.577: Map camera change
03-23 15:51:15.668: Map movement begin
03-23 15:51:15.669: Map movement end
03-23 15:51:15.669: Map scroll
[More map movement begin/end, scroll and changes]
03-23 15:51:15.710: Map camera change
03-23 15:51:15.718: Map movement begin
[Touch ends]
03-23 15:51:15.718: Map movement end
[Here, no movement according to callbacks]
03-23 15:51:15.718: Map scroll
03-23 15:51:15.719: Map camera change
03-23 15:51:15.719: Map movement begin
03-23 15:51:15.720: Map camera change
03-23 15:51:15.720: Map fling
03-23 15:51:15.731: Map camera change
[More map camera changes]
03-23 15:51:16.092: Map camera change
03-23 15:51:16.102: Map movement end
03-23 15:51:16.108: Map camera change
[More map camera changes]
03-23 15:51:16.242: Map camera change

With the version 5.0.0 of the SDK the OnTouchListener became unusable as the MapView always consumes the event, which forces me to add a dummy overlay View above the MapView just to intercept touch down/up events. Not super clean, especially for a method that doesn't completely solve my problem.

Is there an alternative to achieve what I'm looking for, such as a listener I missed?

@tobrun tobrun added the Android Mapbox Maps SDK for Android label Mar 24, 2017
@tobrun
Copy link
Member

tobrun commented Mar 24, 2017

@Jukurrpa Thank you for reaching out and taking time to write up your issue.
We don't consider overriding onTouch a supported use-case as we try to keep gesture handling business logic internal and expose listeners for each gesture interaction (OnMapLongClickListener, OnMapFlingListener, etc).

You should though be able to detect the map being idle using the OnMapChangeListener and setting up an idle timeout that is triggered when the map hasn't received any changes during the timeout period. Can you let me know which MapChange events you are currently hooking into?

Additionally we are thinking about improving our OnCameraChangeListener with callbacks that indicate which kind of interaction occurred in #6350.

To close this issue, I think it would be a good idea to either add an example of this in the testapp of this repository or in mapbox-android-demo.

@mpuchala
Copy link

mpuchala commented Mar 24, 2017

Hey @tobrun,

I have more or less similar problem. Right now on 4.1 I'm using my custom onTouchListener on MapView. After switching to 5.0.0 it looks like it's not registered - I use stable versions.

I found some listeners:

  • onScrollListener looks fine but it's not enough - I don't have information when touch started and ended
  • onMapClickListener can be helpful but beside LatLng it would be nice to have position on view

It's still not enough - probably I can't get information when touch ended. Do you have any sugestion how can I resolved my problem without many hacks? Maybe it's (I haven't found the way) or would be possible to register custom listener for GestureDetector? Having onMoveBegin, onMove, onMoveEnd would be perfect.
I prefer to use gestures instead of checking camera position LatLng, zoom, etc. My case is related to other UI elements.
I'm looking for any interesting solution - right now it's our blocker...

tl;dr
Worked on 4.1 but on 5.0 not and we have to resolve this in some way.

mapView.setOnTouchListener(this::onTouchListener);

private boolean onTouchListener(View view, MotionEvent motionEvent) {
   (...)
    mMoveGestureDetector.onTouchEvent(motionEvent);

    return false;
}

private MoveGestureDetector mMoveGestureDetector = new MoveGestureDetector(mContext, new MoveGestureDetector.SimpleOnMoveGestureListener() {
        @Override
        public void onMoveEnd(MoveGestureDetector detector) {
            if (detector.getFocusDelta().length() > Consts.Map.MIN_GESTURE_DELTA) {
                mMapObserverCallback.onLongMoveGesture();
            }
        }
    });

@tobrun
Copy link
Member

tobrun commented Mar 24, 2017

The PRs responsible for this change will be #8272 in combination with #8447. If you are not using MarkerViews atm you can workaround this by toggling the visibility of the MarkerViewContainer. withMarkerViewManager.getMarkerViewContainer().setVisibility(View.Gone). (though haven't been able to verify this).

@mpuchala
Copy link

Any suggestion for my problem to avoid duplicate issue? Actually it's not related to any element of map.

@tobrun tobrun added this to the android-v5.1.0 milestone Mar 24, 2017
@Jukurrpa
Copy link
Author

@tobrun thanks for the answer and clearing up the OnTouchListener situation, it makes sense. The only issue is that with the v5 of the SDK there is no way to tell if the user is currently touching the map except by using a dummy overlay. It'd be nice to have a listener to make up for it.

I'm using these events in OnMapChangedListener: REGION_WILL_CHANGE, REGION_WILL_CHANGE_ANIMATED, REGION_DID_CHANGE and REGION_DID_CHANGE_ANIMATED. It'd be great if map did change events weren't called if the map is still moving.

Using a timer works indeed but adds an artificial waiting time for the user in addition to whatever is done when the map stops moving (http request in my case), which is not great even if it's a couple of tenths of second.

The changes on OnCameraChangeListener in the issue you linked would be great. I would even do the same on OnScrollListener and OnFlingListener (distinguish start and stop) as for now they are "single point" callbacks for events that last a few moments.

Not sure how I can contribute as I don't have much free time to work on the SDK itself, but I can share what I'll put together using a timer, even if it's not a perfect solution.

@tobrun
Copy link
Member

tobrun commented Mar 30, 2017

#8585 reverts touch changes made for the 5.0.0 release, we are planning a 5.0.2 shortly containing this fix. For the future 5.1.0 release we will be tackling #6350 so there isn't a need for overriding onTouch. Thank you all for the valuable feedback. Closing for now

@tobrun tobrun closed this as completed Mar 30, 2017
@tobrun tobrun modified the milestones: android-v5.0.2, android-v5.1.0 Mar 30, 2017
@Jukurrpa
Copy link
Author

Thanks for the update, looking forward to the 5.1.0!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Android Mapbox Maps SDK for Android
Projects
None yet
Development

No branches or pull requests

3 participants