|
| 1 | +import { Camera, MapView, MarkerView } from '@rnmapbox/maps'; |
| 2 | +import { useEffect, useState } from 'react'; |
| 3 | +import { Platform, Pressable, StyleSheet, Text, View } from 'react-native'; |
| 4 | + |
| 5 | +const POSITIONS = Object.fromEntries([ |
| 6 | + ['id1', [-1.202582, 43.36005] as [number, number]], |
| 7 | + ['id2', [-1.303701, 43.384357] as [number, number]], |
| 8 | +]); |
| 9 | + |
| 10 | +type Rider = { |
| 11 | + id: string; |
| 12 | + name: string; |
| 13 | + order: number; |
| 14 | +}; |
| 15 | + |
| 16 | +const RIDERS: Rider[] = [ |
| 17 | + { id: 'id2', name: 'Favorite Rider', order: 100 }, |
| 18 | + { id: 'id1', name: 'Normal Rider', order: 10 }, |
| 19 | +]; |
| 20 | + |
| 21 | +export const Test = () => { |
| 22 | + const [selectedId, setSelectedId] = useState<string | null>(null); |
| 23 | + const [positions, setPositions] = useState<Record<string, [number, number]>>({}); |
| 24 | + |
| 25 | + useEffect(() => { |
| 26 | + const interval = setInterval(() => { |
| 27 | + setPositions(POSITIONS); |
| 28 | + }, 1000); |
| 29 | + return () => clearInterval(interval); |
| 30 | + }, []); |
| 31 | + |
| 32 | + const labels = RIDERS.map(rider => ({ |
| 33 | + ...rider, |
| 34 | + order: rider.id === selectedId ? 10000 : rider.order, |
| 35 | + selected: rider.id === selectedId, |
| 36 | + })).sort((a, b) => a.order - b.order); |
| 37 | + |
| 38 | + return ( |
| 39 | + <View style={StyleSheet.absoluteFill}> |
| 40 | + <MapView |
| 41 | + style={{ flex: 1 }} |
| 42 | + onPress={() => { |
| 43 | + if (Platform.OS !== 'web') setSelectedId(null); |
| 44 | + }}> |
| 45 | + <Camera centerCoordinate={[-1.21, 43.38]} zoomLevel={10} /> |
| 46 | + |
| 47 | + {labels.map(label => { |
| 48 | + const position = positions[label.id]; |
| 49 | + if (!position) return null; |
| 50 | + |
| 51 | + return ( |
| 52 | + <MarkerView |
| 53 | + key={label.id} |
| 54 | + id={label.id} |
| 55 | + coordinate={position} |
| 56 | + anchor={{ x: 0, y: 1 }} |
| 57 | + allowOverlap={false} |
| 58 | + isSelected={label.selected}> |
| 59 | + <Pressable onPress={() => setSelectedId(label.id)}> |
| 60 | + <View |
| 61 | + style={{ |
| 62 | + borderRadius: 16, |
| 63 | + borderWidth: 2, |
| 64 | + borderColor: label.selected ? '#fff' : '#4CAF50', |
| 65 | + backgroundColor: label.selected ? '#fff' : '#4CAF50', |
| 66 | + }} |
| 67 | + collapsable={false}> |
| 68 | + <Text style={{ fontSize: 16, color: label.selected ? '#4CAF50' : '#fff' }}> |
| 69 | + {label.name} |
| 70 | + </Text> |
| 71 | + </View> |
| 72 | + </Pressable> |
| 73 | + </MarkerView> |
| 74 | + ); |
| 75 | + })} |
| 76 | + </MapView> |
| 77 | + </View> |
| 78 | + ); |
| 79 | +}; |
| 80 | + |
| 81 | +export default Test; |
| 82 | + |
| 83 | +/** @type ExampleWithMetadata['metadata'] */ |
| 84 | +const metadata = { |
| 85 | + title: 'MarkerView Disappear (Issue 4206)', |
| 86 | + tags: ['MarkerView', 'bug', 'isSelected'], |
| 87 | + docs: 'Exact reproducer from issue #4206: MarkerViews disappear on Android when width/height is 0 during addViewAnnotation.', |
| 88 | +}; |
| 89 | +Test.metadata = metadata; |
0 commit comments