react-nativereact-native-maps

MapView Callout onPress not triggering


I've got a MapView from and I'm trying to render a location button, which is currently rendered in a callout and says "Find Me." The code is below.

The button displays nicely, but I can't get the onPress to work: when I click "Find Me", neither the "callout hello" or "button hello" log statements are logged, so nothing has been pressed (the button doesn't show any opacity on press either).

I've also tried rendering the button without the callout. It displays but still isn't pressed.

Help!


import React, { Component } from "react";
import { MapView } from "expo";
import { View, Button } from "react-native";
import { BLText } from "../components/StyledComponents";
import F8StyleSheet from "../components/F8StyleSheet";
import { connect } from "react-redux";
const { Marker, Callout } = MapView;
import { getLocationAsync } from "../redux/actions/userActions";

FindMeButton = ({ onPress }) => {
  return (
    <Callout
      style={styles.locationButtonCallout}
      onPress={() => console.log("callout hello")}
    >
      <Button
        onPress={() => console.log("button hello")}
        title={"Find Me"}
        style={styles.locationButton}
      />
    </Callout>
  );
};

class MapScreen extends Component {
  static navigationOptions = {
    title: "Nearby Stations"
  };

  renderMarkers() {
    return (markers = Object.keys(this.props.stations).map(key => {
      const station = this.props.stations[key];
      return (marker = (
        <Marker
          key={key}
          // onPress={this.onMarkerPress.bind(this, station)}
          coordinate={{
            latitude: Number(station.location.lat),
            longitude: Number(station.location.lng)
          }}
        >
          <Callout
            onPress={() => {
              this.props.navigation.navigate("ListScreen");
              // this.props.navigation.navigate("StationDetail", {
              //   title: station.title
              // });
            }}
          >
            <BLText>{station.title}</BLText>
          </Callout>
        </Marker>
      ));
    }));
  }

  render() {
    console.log("rendering at region:", this.props.userLocation);

    return (
      <View style={styles.container}>
        <MapView
          provider={MapView.PROVIDER_GOOGLE}
          style={{ flex: 1 }}
          region={this.props.userLocation}
          showsUserLocation={true}
        >
          {this.renderMarkers()}
          <FindMeButton onPress={this.props.getLocationAsync} />
        </MapView>
      </View>
    );
  }
}

const mapStateToProps = state => {
  return {
    stations: state.main.stations,
    userLocation: state.main.currentRegion
  };
};

export default connect(
  mapStateToProps,
  { getLocationAsync }
)(MapScreen);

const styles = F8StyleSheet.create({
  locationButtonCallout: {
    borderRadius: 0,
    opacity: 0.8,
    backgroundColor: "lightgrey",
  },
  locationButton: {
    backgroundColor: "lightgrey",
    borderRadius: 10,
    opacity: 0.8
  },
  container: {
    flex: 1,
    flexDirection: "row",
    justifyContent: "center"
  }
});


Solution

  • The Callout needs to be a sibling of MapView, not a child.

    (updating with details by request, a year later)

    Here's what Callout being a child means:

    <MapView>
      <Callout/>
    </MapView>
    

    Here's what Callout being a sibling means:

    <MapView/>
    <Callout/>