Platform: Android 4.4.4
Mapbox SDK version: 4.2.1
map.addMarker(new MarkerViewOptions()....) - parameters doesn't matter. OR You can just move the map viewport far away from the existing marker.map.moveCamera() or map.easeCamera(), or map.animateCamera(), it doesn't matterCamera moves, and you can see your marker on map.
Camera moves, but you can't see marker UNLESS you move the map by touching it (non-programmatically). The marker will stay invisible if you will not move the map by touching it, and it will instantly appear as you start moving the map.
I suspect there are some marker visibility checks inside the mapbox SDK which are done when moving the map by touching it, and not done when moving the camera programmatically.
I found very ugly workaround which works 80% of the time:
final CameraUpdate center = CameraUpdateFactory.newCameraPosition(newPosition);
map.animateCamera(center, new MapboxMap.CancelableCallback() {
@Override
public void onCancel() {
}
@Override
public void onFinish() {
handler.postDelayed(new Runnable() {
@Override
public void run() {
map.moveCamera(center);
}
}, 100);
}
});
That is, repositioning camera again when marker is INSIDE the viewport seems to fix it. But not always. Sometimes even more weird behaviour happens, the marker disappears until I zoom out. And it will disappear again if I zoom in...
Thanks you for the report, as workaround for now you can do MapboxMap.getMarkerViewManager().invalidateViewMarkersInVisibleRegion() in the onFinish() of the animateCamera callback.
tobrun, thanks for your reply, the "solution" you provided helps partially, but not with those "visible only when you zoom out" markers.
It seems that I narrowed the problem. If you move the marker which is outside the viewport (using marker.setPosition(..)), it looks like it's visibility is still calculated based on its previous position. So if you zoom out the map enough, marker's previous position becomes visible, and so the marker view itself becomes visible, too. Is there any way to "force sync" marker and corresponding view position? calling MapboxMap.getMarkerViewManager().invalidateViewMarkersInVisibleRegion() after calling marker.setPosition(..)) doesn't help.
@deinlandel thank you for following up with the detailed analysis, I was able to reproduce the issue and narrowed down to the asynchronous update behavior of Markers. A patch for animate and ease was straightforward since I could hook into the related MapChange events but for moveTo (jumpTo in core) we don't have them in the Android binding. This has been an issue in the past where we workaround this with:
// MapChange.REGION_DID_CHANGE_ANIMATED is not called for `jumpTo`
// invalidate camera position to provide OnCameraChange event.
invalidateCameraPosition();
Adding a line to invalidate the markers will not work here as markers updates are asynchronous.
Going to look more into the underlying code and see if I can hook into/rewire something else to provide invalidation.
tobrun, thanks for trying to fix the issue. I'm still hoping for some kind of workaround, I'm working on a tracking application, so moving markers are crucial part of user experience...
I was able to fix this issue with porting the same solution to the issue we had with adding a MarkerView (also asynchronous). By callling MarkerViewManager.setWaitForRenderInvoke(true) as part of Marker.setPosition() the MarkerView is correclty invalidated.
This example below start with the camera pointing at Grenoble and having a MarkerView in Australia. After 3 seconds it will update the MarkerView to Paris and I immediately call one of the camera updates to move to Paris without a duration:

@deinlandel, I believe you can backport this solution to 4.2.1. Can you add an OnMapChangeListener to your MapView and check for MapView.DID_FINISH_RENDERING_FRAME_FULLY_RENDERED after you called addMarker? in this callback you can call invalidateViewMarkersInVisibleRegion. Note: don't forget to remove the listerener after getting the correct event.
tobrun, unfortunately, your proposed backport didn't work. I attached a video illustrating the issue:
https://www.youtube.com/watch?v=7Wau5SXkpI0
The marker has "trail" consisting of polylines (which render correctly), so it's pretty obvious when marker gets invisible. As you can see, even programmatic camera movement is not needed. If invisible marker's position changes to position which is inside the viewport, it starts rendering incorrectly.
I'm not sure if this will work for you all, but what we seemed to have success with is calculating how far away the marker is from the current map position. If the marker is most likely out of the visible region then we remove and re-add the marker instead of changing the markers position using setPosition(). We are very thankful for the MapBox and the dedication of the developers on this project. Thank you.
@tobrun sorry to bother you again, I just wanted to make sure: have you seen the video? Does your fix cover the situation shown on the video?
@deinlandel no problem, I think the issue shown in the video is different as it's related to the invalidation region. The underlying issue is that MarkerViews are actually Android SDK Views ghosting a 1px-1px GL Marker on the map. Our current implementation doesn't take the difference in size in account so the MarkerView will only show when underlying Marker is panned inside the viewport. One solution for this is taking the size in account or implement #5440.
Seeing that video, I would advice you to look into runtime styling. This is API allows you to have full control over Layers and Sources. You can define you own Source (data) and Layer (SymbolLayer/LineLayer) and add those to the map. These will not suffer from the shown issues and will be much more performant. We have a couple of examples on our webpage and in our test application found in this repo.
Most helpful comment
I found very ugly workaround which works 80% of the time:
That is, repositioning camera again when marker is INSIDE the viewport seems to fix it. But not always. Sometimes even more weird behaviour happens, the marker disappears until I zoom out. And it will disappear again if I zoom in...