LuizfBrisighello
LuizfBrisighello

Reputation: 269

React Native Maps show marker callout

I'm using react-native-maps to render GOOGLE MAPS with loads of markers that I fetch from my co-worker's API. Bellow the map I have a FlatList rendering data from every marker on the screen. The item in FlatList's renderItem is a TouchableOpacity. How can I focus on the marker callout when I press the corresponding button in the list?

ScreenShot:

enter image description here

code:

<Container>
  <StatusBar
    barStyle={theme.colors.statusDark}
    backgroundColor={theme.colors.background1}
  />
  <GoogleMaps>
    {markers.map(marker => (
      <MyMarker
        key={marker.uid}
        identifier={marker.uid}
        markerLatitude={marker.position.lat}
        markerLongitude={marker.position.lng}
        title={marker.name}
        address={marker.address}
        cashback={marker.cashback}
      />
    ))}
  </GoogleMaps>
  <DivisorSimple />
  <ListContainer>
    {fetchIsLoading ? (
      <ActivityIndicator size='large' />
    ) : (
      <FlatList
        data={markers}
        renderItem={({ item }) => (
          <ListMapItem
            handleClick={() => {}
            title={item.name}
            address={item.address}
            cashback={item.cashback}
            handleGetRoute={() => handleGetRoute(item.position.lat, item.position.lng)}
          />
        )}
        keyExtractor={item => item.uid}
      />
    )}
  </ListContainer>
</Container>

Upvotes: 1

Views: 4578

Answers (1)

Max
Max

Reputation: 4739

Animating map to marker is done imperatively, so you need to get a reference to your MapView component, e.g. add this prop to MapView:

<MapView
  ...
  ref={ref => this.map = ref}
>
  {data.map(item => <Marker ... />)}
</MapView>

In easiest case, this should refer to the component that is also rendering your Markers, so that you can reference this.map in Marker's render. If your MapView component is wrapped into something else, you will need to forward ref to get the ref to the actual MapView component

Then, you need to keep track of Region currently displayed on a map and it's changes when user moves the camera

<MapView
  ...
  onRegionChangeComplete={region => this.setState({ region })}
>

After that you can use MapView's animateToRegion method to focus on marker

// ListMapItem's handleClick prop
handleClick={() => {
      // construct new region from marker's lat/lng
      // and current region's deltas to keep zoom level
      const newRegion = {
        latitude: item.position.lat,
        longitude: item.position.lng,
        latitudeDelta: this.state.region.latitudeDelta,
        longitudeDelta: this.state.region.latitudeDelta,
      }
      // animate camera to that region over 500 ms
      this.map.animateToRegion(newRegion, 500)
    }}

Upvotes: 1

Related Questions