Skip to content

[Bug]: On Android, MarkerView sometimes disappear #4206

@scharron

Description

@scharron

Mapbox Version

default

React Native Version

0.83.6

Platform

Android

@rnmapbox/maps version

10.3.0

Standalone component to reproduce

import Mapbox, { Camera, MapView, MarkerView } from '@rnmapbox/maps';
import { useEffect, useState } from 'react';
import { Platform, Pressable, StyleSheet, Text, View } from 'react-native';

Mapbox.setAccessToken(
  'XXX'
);

const POSITIONS = Object.fromEntries([
  ['id1', [-1.202582, 43.36005] as [number, number]],
  ['id2', [-1.303701, 43.384357] as [number, number]],
]);

type Rider = {
  id: string;
  name: string;
  order: number;
};

const RIDERS: Rider[] = [
  { id: 'id2', name: 'Favorite Rider', order: 100 },
  { id: 'id1', name: 'Normal Rider', order: 10 },
];

export const Test = () => {
  const [selectedId, setSelectedId] = useState<string | null>(null);
  const [positions, setPositions] = useState<Record<string, [number, number]>>({});

  useEffect(() => {
    const interval = setInterval(() => {
      setPositions(POSITIONS);
    }, 1000);
    return () => clearInterval(interval);
  }, []);

  const labels = RIDERS.map(rider => ({
    ...rider,
    order: rider.id === selectedId ? 10000 : rider.order,
    selected: rider.id === selectedId,
  })).sort((a, b) => a.order - b.order);

  return (
    <View style={StyleSheet.absoluteFill}>
      <MapView
        style={{ flex: 1 }}
        onPress={() => {
          if (Platform.OS !== 'web') setSelectedId(null);
        }}>
        <Camera centerCoordinate={[-1.21, 43.38]} zoomLevel={10} />

        {labels.map(label => {
          const position = positions[label.id];
          if (!position) return null;

          return (
            <MarkerView
              key={label.id}
              id={label.id}
              coordinate={position}
              anchor={{ x: 0, y: 1 }}
              allowOverlap={false}
              isSelected={label.selected}>
              <Pressable onPress={() => setSelectedId(label.id)}>
                <View
                  style={{
                    borderRadius: 16,
                    borderWidth: 2,
                    borderColor: label.selected ? '#fff' : '#4CAF50',
                    backgroundColor: label.selected ? '#fff' : '#4CAF50',
                  }}
                  collapsable={false}>
                  <Text style={{ fontSize: 16, color: label.selected ? '#4CAF50' : '#fff' }}>
                    {label.name}
                  </Text>
                </View>
              </Pressable>
            </MarkerView>
          );
        })}
      </MapView>
    </View>
  );
};

Observed behavior and steps to reproduce

On my app, when clicking on a MarkerView, its isSelected is modified, and the content is re-rendered.
During that time, my app do other work on the map (display / hide some lines)
Randomly, when changing the selection, the modified MarkerViews disappear from the map.
Moving the map does not make them reappear.
Using the element inspector, I can see the touchables are still there. Also with devtools, the MarkerViews and children are still in the tree.
Changing the selection again for those disappeared MarkerViews does not make them reappear.

Expected behavior

They should still be visible.

Notes / preliminary analysis

Adding logs in RNMBXMarkerView.kt in getOffset, mView is never null, but view.width and view.height are both 0
Asking copilot about it, he proposed me to modify add to add

        if (view.width == 0 || view.height == 0) {
            Logger.w("RNMBXMarkerView", "0 width / height, waiting next layout")
            // Wait for the next layout via onLayoutChange
            return
        }

before getOptions()

I tried it and it seems to solve it, but since I don't understand how all this works, I'm not sure this is a valid patch.
Copilot says that addViewAnnotation should be called only when layouting is done, and that's not the case when width = 0 and height = 0
This bug may appear because my app is quite heavy on MarkerViews, and so layout may be slower than expected.

Additional links and references

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions