首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >响应本机地图标注呈现

响应本机地图标注呈现
EN

Stack Overflow用户
提问于 2020-01-22 17:30:16
回答 2查看 5K关注 0票数 4

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

问题是,每个标注都是在地图上的每个标记的背景中呈现的。另外,每个标注都是重新呈现的,因为我有来自实时API的新数据。这将导致数百个视图被呈现,即使我只需要按下标记的标注。

是否有一种方法可以确保在用户按下特定标记之前不呈现任何标注?在按下之后,我还想确保只有特定标记的标注被呈现和显示。

我的代码:

MapScreen:

代码语言:javascript
复制
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

标记部分:

代码语言:javascript
复制
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组件:

代码语言:javascript
复制
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
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-06-30 18:39:52

其实我自己找到了答案。我已经创建了对每个标记的引用,然后将一个onPress属性传递给,并将showCallout属性传递给它的标注组件。

标记组件:

代码语言:javascript
复制
export default function Markers() {
  const {
    stations: { station }
  } = require("../../bartData/stations");

  const [clickedMarkerRef, setClickedMarkerRef] = useState(null)

  return station.map((trainStation, index) => {
    return (
      <MapView.Marker
        key={trainStation.abbr}
        coordinate={{
          latitude: parseFloat(trainStation.gtfs_latitude),
          longitude: parseFloat(trainStation.gtfs_longitude)
        }}
        image={Platform.OS === "ios" ? station_ios : station_android}
        zIndex={100}
        tracksInfoWindowChanges={true}
        onPress={() => setClickedMarkerRef(index)}
      >
        <CalloutContainer
          key={trainStation.abbr}
          stationName={trainStation.name}
          stationAbbr={trainStation.abbr}
          showCallOut={clickedMarkerRef === index}
        />
      </MapView.Marker>
    );
  });
}

而Callout组件只在showCallOut为真时才获取数据。标注组件中的

代码语言:javascript
复制
useEffect(() => {
    if (props.showCallOut === true) {
      fetchTrainDepartures();

      const intervalId = setInterval(fetchTrainDepartures, 10000);
      return () => clearInterval(intervalId);
    }
  }, []);

因此,除非单击标记,否则本地状态保持为null,而回调不会获取任何数据。

单击索引0处的标记时:

  • clickedMarkerRef现在是0。
  • showCallout是真=> {clickMarkerRef ===索引}
  • 在Callout.js文件下的useEffect钩子中,=> props.showCallout为true。
  • 数据仅为此标注获取。
票数 0
EN

Stack Overflow用户

发布于 2020-01-22 18:54:40

在ComponentDidMount上,您应该获取所有列车的数据,以便能够在它们的位置上设置所有标志。您可以使用firebase的一次(“value”)事件来完成此操作--该事件在调用时只从引用中获取一次数据,因此您将在组件did挂载上调用它。

多读一次(“价值”)

现在,当你有所有的指针在他们的位置,用户可以点击任何一个指针来跟踪它的运动,对吗?

所以每个指针必须有一些独特的东西,比如列车ID或者我不知道你的数据库结构的东西,所以我假设你有火车ID,现在在标记的onPress函数中,你应该传递这个TrainID。

示例:

代码语言:javascript
复制
onPress={()=> this.TrackSpecificTrain(trainID)  }

现在,在TrackSpecificTrain函数中,您应该使用列车ID和firebase 关于(“价值”)事件调用您的数据库重构,现在您将继续获取所选列车的实时数据,并且您可以使用来自防火墙的新数据更新您的本地状态stationData

示例

代码语言:javascript
复制
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,并停止跟踪前一个标记!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59865227

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档