React Native Maps Callout Rendering

问题描述 投票:0回答:1

我正在使用react-native-maps显示我所在地区的火车站的标记。每个标记都有一个标注,其中包含接近列车的实时数据。

问题是;我在地图上的每个标记的每个标注都在后台呈现。另外,由于我有来自实时API的新数据,每个标注也会重新呈现。即使我只需要按下标记的标注,这也会导致数百个视图被渲染。app screenshot

是否有一种方法可以确保在用户按下特定标记之前不会呈现任何标注?在新闻之后;我还想确保仅渲染和显示特定标记的标注。

我的代码:

MapScreen:

const MapScreen = props => {
  // get user location from Redux store
  // this is used to center the map
  const { latitude, longitude } = useSelector(state => state.location.coords)

  // The MapView and Markers are static
  // We only need to update Marker callouts after fetching data
  return(
    <SafeAreaView style={{flex: 1}}>
    <MapView
        style={{flex: 1}}
        initialRegion={{
          latitude:  parseFloat(latitude) || 37.792874,
          longitude: parseFloat(longitude) || -122.39703,
          latitudeDelta: 0.06,
          longitudeDelta: 0.06
        }}
        provider={"google"}
      >
        <Markers />
      </MapView>
      </SafeAreaView>
  )
}

export default MapScreen

标记组件:

const Markers = props => {
  const stationData = useSelector(state => state.stationData)

  return stationData.map((station, index) => {
    return (
      <MapView.Marker
        key={index}
        coordinate={{
          // receives station latitude and longitude from stationDetails.js
          latitude: parseFloat(stationDetails[station.abbr].gtfs_latitude),
          longitude: parseFloat(stationDetails[station.abbr].gtfs_longitude)
        }}
        image={stationLogo}
        zIndex={100}
        tracksInfoWindowChanges={true}
      >
        <MapView.Callout
          key={index}
          tooltip={true}
          style={{ backgroundColor: "#ffffff" }}
        >
          <View style={styles.calloutHeader}>
            <Text style={{ fontWeight: "bold" }}>{station.name}</Text>
          </View>
          <View style={styles.calloutContent}>
            <StationCallout key={index} station={stationData[index]} />
          </View>
        </MapView.Callout>
      </MapView.Marker>
    );
  });
};

StationCallout组件:

const StationCallout = (props) => {
  return(
    props.station.etd.map((route, index) => {
      const approachingTrains = function() {
        trainText = `${route.destination} in`;

        route.estimate.map((train, index) => {
          if (index === 0) {
            if (train.minutes === "Leaving") {
              trainText += ` 0`;
            } else {
              trainText += ` ${train.minutes}`;
            }
          } else {
            if (train.minutes === "Leaving") {
              trainText += `, 0`;
            } else {
              trainText += `, ${train.minutes}`;
            }
          }
        });

        trainText += " mins";

        return <Text>{trainText}</Text>;
      };

      return <View key={index}>
      {approachingTrains()}
      </View>;
    })
  )
};

export default StationCallout
javascript react-native google-maps react-native-maps
1个回答
0
投票

在ComponentDidMount上,您应该获取所有列车的数据,以便可以将所有标记设置在它们的位置。您可以使用firebase的一次('value')事件来执行此操作,此事件在调用时仅从引用中获取一次数据,因此您将在组件确实挂载时调用它。

READ MORE ABOUT ONCE('VALUE')

现在,由于所有指针都在其位置上,用户可以单击任一指针以跟踪Track It的运动对吗?

因此,每个指针必须具有唯一的名称,例如Train ID,或者我不知道您的数据库结构,因此我假设您具有Train ID,现在,在标记的onPress函数中,您应该传递此TrainID。

示例:

onPress={()=> this.TrackSpecificTrain(trainID)  }

现在在TrackSpecificTrain函数中,您应该使用火车ID和firebase on('value')事件调用数据库参考,现在您将继续获取所选火车的实时数据,并且可以使用新的更新本地状态stationData数据来自firebase。

示例


TrackSpecificTrain=(trainID)=>{
const ref = database().ref(`YourTrainsRef/${trainID}/`)
  ref.on('value',( snapshot)=>{
           //Update your local state with new data in snapshot
        })
}


RemoveTracker=(trainID)=>{
const ref = database().ref(`YourTrainsRef/${trainID}/`)

ref.off("value")

}

现在我们也使用RemoveTracker,因为如果用户单击另一个标记,您可能需要停止跟踪先前的火车,因此它将开始跟踪新标记上的trainID并停止跟踪先前的火车!。

© www.soinside.com 2019 - 2024. All rights reserved.