【问题标题】:React Native Expo MapView - Passing Marker Details to an Expanding Bottom ViewReact Native Expo MapView - 将标记详细信息传递给扩展的底部视图
【发布时间】:2021-11-30 23:01:38
【问题描述】:

我正在使用 React Native Expo 构建一个应用程序,该应用程序具有各种标记的屏幕。这些来自 firebase JSON 文件。一切正常,除了屏幕底部的视图,我想在单击时在标记点上显示信息(标题、描述、附加图像等)。

我尝试了多种方法,在此示例中使用 map 方法,但是这会在底部视图中一次显示所有标记。我只想显示当前选择的标记。这个底视图还具有最小化/扩展的功能,这是无关紧要的。

我添加了一个 onPress 事件,我希望它将当前显示的标记设置为按下的标记。

这是我所做的:

// ## Imports
// ## Firebase codeblock

function MapExp() {

   // I've removed irrelevant constants/functions for minimizing bottom view.
   
   // Initial empty array of users (marker points)
   const [users, setUsers] = useState([]); 
   const windowHeight = Dimensions.get("window").height;

   const [point, setPoint] = useState([]);

   const pressMarker = (i) => {
      console.log(i.Title);
      console.log(i.Description);
      setPoint(i.Title);
    };

   useEffect(() => {
      const dbh = firebase.firestore();
      dbh
      .collection("Map_DB")
      .get()
      .then((querySnapshot) => {
         const users = [];
         querySnapshot.forEach((documentSnapshot) => {
            users.push({
               ...documentSnapshot.data(),
               key: documentSnapshot.id,
            });
         });
         // Filling array 'users' with all the map markers from DB
         setUsers(users);
      });
   }, []);

   
   return (
      <MapView
        initialRegion={{ latitude: 48.87389506, longitude: 2.295039178, latitudeDelta: 0.01, longitudeDelta: 0.01 }}
        r
        style={{ flex: 1, minHeight: windowHeight }}
        provider={PROVIDER_GOOGLE}
        customMapStyle={mapStyle}
        showsUserLocation={true}
      >
       {users.map((i, index) => (
          <Marker
            key={index}
            onPress = {() => pressMarker(i)}
            coordinate={{
              latitude: i.Latitude,
              longitude: i.Longitude,
            }}
            title={i.Title}
            description={i.Description}
          />
        ))}
      </MapView>

      {/* ##### ATTEMPTING TO ADD EXPAND VIEW ###### */}
      {users.map((i, index) => (
         <View style={styles.expandingView}>
            <TouchableOpacity style={styles.touchableButton } onPress={toggleCollapsed}>
               <Image source={require("../assets/upArrowWhite.png")} style={styles.arrowLogo}></Image>
            </TouchableOpacity>
            <Animated.View style={{maxHeight: animationHeight}}>
               <View style={styles.pointImageContainer}>
                  <Image style={styles.pointImage} source={require("../assets/sunsetCrop.png")}  />
               </View>
               <View style={styles.paragraphContainer}>
                  <Text style={styles.paragraph}>{i.Title}</Text>
                  <Text style={styles.paragraph}>{i.Description}</Text>
               </View>
            </Animated.View>
         </View>
      ))}
  );
}
I have also added the console log statements to see if I can correctly log the currently pressed marker's details 

export default MapExp;

pressMarker 应该触发 setPoint,但我不确定如何执行此操作。然后我希望底部视图“展开视图”将标题等显示为文本。

有没有更好的方法将当前标记数据传递到屏幕的展开视图/文本组件中?

在 pressMarker 事件中,我也可以成功登录控制台,按下标记标题和描述没有问题:

pressMarker = (i) => {
      console.log(i.Title);
      console.log(i.Description);
      setPoint(i.Title);

问题是将当前“点”设置为所选标记,以显示在屏幕底部的展开视图中。

【问题讨论】:

    标签: javascript react-native expo marker


    【解决方案1】:

    首先,您需要创建一个组件来显示标记的额外细节。它可以是一个单独的组件或隐式定义。

    要在显示/隐藏Details 组件之间切换,您需要为users 数组中的每个对象添加showDetails: false 属性。

    也不要忘记为每个元素使用一个 id

    示例数据如下所示:

    const users = [
      {id: 0, title: 'first point', description: '', coordinatets: {lat: 0, long: 0}, showDetails: false},
      // rest of the data...
    ]
    

    如下所示,我将Marker 和Details 包装为TouchableOpacity 元素,可以根据您的需要进行更改。

    function MarkerWithDetails({point, onToggle}) {
      const {coordinates, title, description, showDetails} = point;
    
      return(
        <TouchableOpacity onPress={onToggle}>
          <Marker coordinate={{latitude: lat, longitude: long}}/>
          {showDetails && <Details title={title} description={description}/>}
        </TouchableOpacity>
      )
    }
    

    现在,Details 组件仅在具有 showDetails: true 属性时才会呈现额外的细节。

    现在是渲染 MarkerWithDetails 的时候了,您还需要一个处理函数来通过在 false 和 true 之间更改 showDetails 值来在隐藏和显示 Details 之间切换>:

    handleToggle = (id) => {
      setUsers(prevState => prevState.map(user => (  
            user.id === id ? {...user, showDetails: !user.showDetails} : user     
         ))
      )
    }
    
    return (
        <MapView
            initialRegion={{ latitude: 48.87389506, longitude: 2.295039178, latitudeDelta: 0.01, longitudeDelta: 0.01 }}
            r
            style={{ flex: 1, minHeight: windowHeight }}
            provider={PROVIDER_GOOGLE}
            customMapStyle={mapStyle}
            showsUserLocation={true}
          >
           {users.map((user) => (<MarkerWithDetials point={user} onToggle={() => handleToggle(user.id)}/>))}
        </MapView>
    )
    

    【讨论】:

    • 非常感谢,我会应用这个。它是否也适用于我的 Firebase 数据。在您的示例中,数据似乎是作为 JSON 样式的 Const 的静态文本,但我的是从 firebase 中提取 json。
    • 正如您告诉我的,数据将从 firebase 到达,然后您将其设置为“用户”状态,因此用户是一个没有“showDetails”属性的对象数组。但在您的情况下,您需要将此属性添加到您的对象中以单独控制每个点的可见性。 @RickPeck
    猜你喜欢
    • 2020-05-07
    • 2023-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-31
    • 2016-08-08
    相关资源
    最近更新 更多