Alex Khanas
Alex Khanas

Reputation: 345

React Native. Show component next to the marker

Is there a way to create a popup similar to the one shown below .

Im using react-native-maps, google provider and markers which are working well, it is only the popup next to the marker that i am having issues with

enter image description here

Upvotes: 0

Views: 685

Answers (1)

bas
bas

Reputation: 15722

We can use the Callout component to do this.

The Callout component accepts a custom view and is flexible in what content it accepts:

Callouts to markers can be completely arbitrary react views, similar to markers. As a result, they can be interacted with like any other view.

Source: https://github.com/react-native-community/react-native-maps#custom-callouts


So an example fitted to your use case looks something like this:

const CustomCalloutView = ({ marker }) => (
  <View>
    <View style={{ flex: 1, flexDirection: "row" }}>
      <Text>Kyiv Ukraine</Text>
      <Badge value="2" status="warning" />
    </View>
    <Text>+1°</Text>
  </View>
);

// ...

<Marker coordinate={marker.latlng}>
  <Callout>
    <CustomCalloutView marker={{...marker}} />
  </Callout>
</Marker>

For the badge I've used the badge the react-native-elements library provides (https://react-native-elements.github.io/react-native-elements/docs/badge), but you can change this to whatever you want.


To make the CustomCalloutView content dynamic based on the marker coordinates passed as props you could use the function reverseGeocodeAsync from expo-location to get info about the location.

Source: https://docs.expo.io/versions/latest/sdk/location/#locationreversegeocodeasynclocation.

Example using dynamic marker coordinates and expo-location:

import * as Location from "expo-location";
// ...

const CustomCalloutView = ({ marker }) => {
  const [location, setLocation] = useState(null);

  useEffect(() => {
    Location.reverseGeocodeAsync(marker).then(res => {
      setLocation(res[0]);
    });
  }, []);

  return (
    <View>
      {location && (
        <View>
          <View style={{ flex: 1, flexDirection: "row" }}>
            <Text>{`${location.city}, ${location.country}`}</Text>
            <Badge value="2" status="warning" />
          </View>
          <Text>+1°</Text>
        </View>
      )}
    </View>
  );
};

Upvotes: 2

Related Questions