【问题标题】:How to create an onPress event that dismisses a callout?如何创建取消标注的 onPress 事件?
【发布时间】:2022-12-20 17:57:03
【问题描述】:

我正在使用 React Native 地图在 React Native 中构建演出指南。

用户会看到一张带有标记的地图,指示演出的位置。当点击这些标记时,会弹出带有演出信息的标注:

当用户点击“Next day's gigs”按钮时,地图会呈现带有标记的标记,显示即将到来的一天的演出。当用户点击这个按钮时,我想确保当按下按钮时,当天所有打开的标注都被取消.关于如何执行此操作的任何建议?

这是渲染地图的组件的代码:

GigMap.js

import { useState, useMemo } from "react";
import {
  StyleSheet,
  Text,
  View,
  Pressable,
  Image,
  TouchableOpacity,
} from "react-native";
import MapView from "react-native-maps";
import { Marker, Callout } from "react-native-maps";
import CalloutView from "./CalloutView";
import { mapStyle } from "../util/mapStyle";
import { useGigs } from "../hooks/useGigs";
import { AntDesign } from "@expo/vector-icons";


const GigMap = ({ navigation }) => {
  const [selectedDateMs, setSelectedDateMs] = useState(Date.now());
  const gigs = useGigs();


  //generates current date in format DD/MM/YYYY
  const selectedDateString = useMemo(() => {
    const date = new Date(selectedDateMs);
    const dateToString = date.toString().slice(0,15)
    return dateToString // returns in form 'Tue Dec 20 2022'
  }, [selectedDateMs]);


  //Filtering through gigs to return only current day's gigs
  const gigsToday = gigs.filter((gig) => {
    const gigDate1 = new Date(gig.dateAndTime.seconds*1000)   
    const gigDate2 = gigDate1.toString().slice(0,15) //return form 'Tue Dec 20 2022'
    return gigDate2 === selectedDateString
  })


  //increments date by amount
  const addDays = (amount) => {
    setSelectedDateMs((curr) => curr + 1000 * 60 * 60 * 24 * amount);
  };

  return (
    <View style={styles.container}>
      <Text style={styles.headerText}>{`Gigs on ${selectedDateString}`}</Text>

      <View style={styles.imageText}>
        <Text style = {styles.subHeader}>Tap on</Text>
        <Image
          style={styles.image}
          source={require("../assets/Icon_Gold_48x48.png")}
        />
        <Text style = {styles.subHeader}> to see gig info</Text>
      </View>

      <MapView
        initialRegion={{
          latitude: -41.29416,
          longitude: 174.77782,
          latitudeDelta: 0.03,
          longitudeDelta: 0.03,
        }}
        style={styles.map}
        customMapStyle={mapStyle}
      >
        {gigsToday.map((gig, i) => (
          <Marker
            key={i}
            coordinate={{
              latitude: gig.location.latitude,
              longitude: gig.location.longitude,
            }}
            image={require("../assets/Icon_Gold_48x48.png")}
            description = 'test'
          >
            <Callout
              style={styles.callout}
              tooltip={true}
              onPress={() =>
                navigation.navigate("GigDetails", {
                  venue: gig.venue,
                  date: selectedDateString,
                  gigName: gig.gigName,
                  image: gig.image
                })
              }
            >
              <CalloutView
                venue={gig.venue}
                gigName={gig.gigName}
                genre = {gig.genre}
              />
            </Callout>
          </Marker>
        ))}
      </MapView>

      <View style={styles.buttonOptions}>
        <TouchableOpacity onPress={() => addDays(-1)} style = {styles.touchable}>
          <AntDesign name="caretleft" size={36} color="#778899" />
          <Text style = {{fontFamily:'Helvetica-Neue', color:'#778899'}}>Previous day's gigs</Text>
        </TouchableOpacity>
        <TouchableOpacity onPress={() => addDays(1)} style = {styles.touchable}>
          <AntDesign name="caretright" size={36} color="#778899" />
          <Text style = {{fontFamily:'Helvetica-Neue',color:'#778899'}}>Next day's gigs</Text>
        </TouchableOpacity>
      </View>
    </View>

  );
};

CalloutView.js

import { StyleSheet, Text, View } from 'react-native';

const CalloutView = ({ venue,gigName,genre }) => {
    const title = gigName.substring(0,25)
    return ( 
        <View style = {styles.container}>
            <Text style = {styles.header} >{`${title}`}</Text>
            <Text style = {styles.details}>{`${venue} | ${genre}`}</Text>
            <Text style = {styles.button}>Tap to see details</Text>
        </View>
     );
}

【问题讨论】:

    标签: react-native react-native-maps


    【解决方案1】:

    由于您已经在使用自定义挂钩 (useGigs),我建议您在该挂钩内处理整个逻辑。

    然而,本质上我们只需要在当前选定日期的状态发生变化时更新todaysGigs

    export function useGigs() {
    
        // however your hook is implemented
         ...
    
        const [currentDate, setCurrentDate] = useState(Date.now())
    
        const incrementCurrentDate = React.useCallback(() => {
            setCurrentDate((curr) => curr + 1000 * 60 * 60 * 24 * 1);
        }, [setCurrentDate])
    
        const decrementCurrentDate = React.useCallback(() => {
            setCurrentDate((curr) => curr + 1000 * 60 * 60 * 24 * (-1));
        }, [setCurrentDate])
    
        const selectedDateString = React.useMemo(() => {
            const date = new Date(selectedDateMs);
            const dateToString = date.toString().slice(0,15)
            return dateToString // returns in form 'Tue Dec 20 2022'
        }, [currentDate]);
        
    
        const gigsToday = React.useMemo(() => {
            return gigs.filter((gig) => {
                const gigDate1 = new Date(gig.dateAndTime.seconds*1000)   
                const gigDate2 = gigDate1.toString().slice(0,15) //return form 'Tue Dec 20 2022'
                return gigDate2 === selectedDateString
         }, [currentDate])
    
    
        return {
            gigsToday,
            gigs,
            incrementCurrentDate,
            decrementCurrentDate,
            selectedDateString,
        }
    }
    

    界面逻辑。

    const GigMap = ({ navigation }) => {
    
      const {selectedDateString, incrementCurrentDate, decrementCurrentDate, gigsToday} = useGigs();
    
      return (
        <View style={styles.container}>
          <Text style={styles.headerText}>{`Gigs on ${selectedDateString}`}</Text>
    
          <View style={styles.imageText}>
            <Text style = {styles.subHeader}>Tap on</Text>
            <Image
              style={styles.image}
              source={require("../assets/Icon_Gold_48x48.png")}
            />
            <Text style = {styles.subHeader}> to see gig info</Text>
          </View>
    
          <MapView
            initialRegion={{
              latitude: -41.29416,
              longitude: 174.77782,
              latitudeDelta: 0.03,
              longitudeDelta: 0.03,
            }}
            style={styles.map}
            customMapStyle={mapStyle}
          >
            {gigsToday.map((gig, i) => (
              <Marker
                key={i}
                coordinate={{
                  latitude: gig.location.latitude,
                  longitude: gig.location.longitude,
                }}
                image={require("../assets/Icon_Gold_48x48.png")}
                description = 'test'
              >
                <Callout
                  style={styles.callout}
                  tooltip={true}
                  onPress={() =>
                    navigation.navigate("GigDetails", {
                      venue: gig.venue,
                      date: selectedDateString,
                      gigName: gig.gigName,
                      image: gig.image
                    })
                  }
                >
                  <CalloutView
                    venue={gig.venue}
                    gigName={gig.gigName}
                    genre = {gig.genre}
                  />
                </Callout>
              </Marker>
            ))}
          </MapView>
    
          <View style={styles.buttonOptions}>
            <TouchableOpacity onPress={() => decrementCurrentDate()} style = {styles.touchable}>
              <AntDesign name="caretleft" size={36} color="#778899" />
              <Text style = {{fontFamily:'Helvetica-Neue', color:'#778899'}}>Previous day's gigs</Text>
            </TouchableOpacity>
            <TouchableOpacity onPress={() => incrementCurrentDate()} style = {styles.touchable}>
              <AntDesign name="caretright" size={36} color="#778899" />
              <Text style = {{fontFamily:'Helvetica-Neue',color:'#778899'}}>Next day's gigs</Text>
            </TouchableOpacity>
          </View>
        </View>
    
      );
    };
    

    【讨论】:

      猜你喜欢
      • 2010-11-23
      • 2022-06-10
      • 2015-06-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-10
      • 1970-01-01
      相关资源
      最近更新 更多