我正在尝试在地图顶部使用Animated.ScrollView
,但没有任何显示。甚至我的5个标记都没有显示。在使用这些代码之前,它是有效的,因为我只是使用MapView
而不是<SetLocationMap />
组件。该地图位于SetLocationMap.js
组件内部。我知道问题出在哪里,我只是不知道如何解决,我想使用我的SetLocationMap.js
组件。
所以我的目标是显示Animated.ScrollView
和我的5个标记。就像在图片上一样:
这是我的代码:
对于EventMap.js
:
this.state = {
controls: {
location: {
value: null
},
},
focusedLocation: {
latitude: 0,
longitude: 0,
// latitudeDelta: 0.04864195044303443,
// longitudeDelta: 0.040142817690068,
latitudeDelta: 0.01,
longitudeDelta: Dimensions.get('window').width / Dimensions.get('window').height * 0.01
},
locationChosen: false,
markerPosition: {
latitude: 0,
longitude: 0
},
markers: [
{
coordinate: {
latitude: 37.42484589323653,
longitude: -122.08271104842426
},
},
{
coordinate: {
latitude: 37.42019338901534,
longitude: -122.08207536488771
},
},
{
coordinate: {
latitude: 37.4219108525511,
longitude: -122.08126466721296
},
},
{
coordinate: {
latitude: 37.42190153308783,
longitude: -122.08728086203337
},
},
{
coordinate: {
latitude: 37.419681603891306,
longitude: -122.08521489053966
},
}
],
}
}
componentWillMount() {
this.index = 0;
this.animation = new Animated.Value(0);
}
componentDidMount() {
// We should detect when scrolling has stopped then animate
// We should just debounce the event listener here
this.animation.addListener(({ value }) => {
let index = Math.floor(value / CARD_WIDTH + 0.3); // animate 30% away from landing on the next item
if (index >= this.state.markers.length) {
index = this.state.markers.length - 1;
}
if (index <= 0) {
index = 0;
}
clearTimeout(this.regionTimeout);
this.regionTimeout = setTimeout(() => {
if (this.index !== index) {
this.index = index;
const { coordinate } = this.state.markers[index];
this.map.animateToRegion(
{
...coordinate,
latitudeDelta: this.state.focusedLocation.latitudeDelta,
longitudeDelta: this.state.focusedLocation.longitudeDelta,
},
350
);
}
}, 10);
});
}
render() {
//For the UserMarker
let userMarker = null;
if(this.state.locationChosen) {
userMarker = <MapView.Marker coordinate={this.state.markerPosition} />
}
//For the Scroll View Card
const interpolations = this.state.markers.map((marker, index) => {
const inputRange = [
(index - 1) * CARD_WIDTH,
index * CARD_WIDTH,
((index + 1) * CARD_WIDTH),
];
const scale = this.animation.interpolate({
inputRange,
outputRange: [1, 2.5, 1],
extrapolate: "clamp",
});
const opacity = this.animation.interpolate({
inputRange,
outputRange: [0.35, 1, 0.35],
extrapolate: "clamp",
});
return { scale, opacity };
});
return(
<View style={styles.container}>
{/* <StatusBar backgroundColor={'transparent'} translucent={true}/> */}
<SetLocationMap
mapContainer={styles.container}
onLocationPick={this.locationPickedHandler}
// onPress={this.pickLocationHandler}
showsUserLocation={true}
ref={ref => this.map = ref} //For animating map movement
>
{userMarker}
{this.state.markers.map((marker, index) => {
const scaleStyle = {
transform: [
{
scale: interpolations[index].scale,
},
],
};
const opacityStyle = {
opacity: interpolations[index].opacity,
};
return (
<MapView.Marker key={index} coordinate={marker.coordinate}>
<Animated.View style={[styles.markerWrap, opacityStyle]}>
<Animated.View style={[styles.ring, scaleStyle]} />
<View style={styles.marker} />
</Animated.View>
</MapView.Marker>
);
})}
</SetLocationMap>
<Animated.ScrollView
horizontal
scrollEventThrottle={1}
pagingEnabled={true}
showsHorizontalScrollIndicator={false}
snapToInterval={snapInterval}
onScroll={Animated.event(
[
{
nativeEvent: {
contentOffset: {
x: this.animation,
},
},
},
],
{ useNativeDriver: true }
)}
style={styles.scrollView}
contentContainerStyle={styles.endPadding}
>
<FlatList
keyExtractor={this._keyExtractor}
horizontal
data={this.props.events}
renderItem={(info) => (
<TouchableOpacity onPress={() => this.itemSelectedHandler(info.item.key)}>
<View style={styles.card} key={info.item.key}>
<Image
source={info.item.image}
style={styles.cardImage}
resizeMode="cover"
/>
<View style={styles.textContent}>
<Text numberOfLines={1} style={styles.cardtitle}>{info.item.name}</Text>
<Text numberOfLines={1} style={styles.cardDescription}>
{info.item.description}
</Text>
</View>
</View>
</TouchableOpacity>
)}
/>
</Animated.ScrollView>
<TouchableOpacity onPress={this.getLocationHandler} style={styles.iconContainer}>
<Icon name="md-locate" size={30} color="blue"/>
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1
},
iconContainer: {
position: 'absolute',
top: 60,
right: 15,
zIndex: 1
},
//--- Style for Marker -----//
scrollView: {
position: "absolute",
bottom: 0,
left: 0,
right: 0,
paddingVertical: 8,
},
endPadding: {
paddingRight: width - CARD_WIDTH,
paddingBottom: 23
},
markerWrap: {
alignItems: "center",
justifyContent: "center",
},
marker: {
width: 8,
height: 8,
borderRadius: 4,
backgroundColor: "rgba(130,4,150, 0.9)",
},
ring: {
width: 24,
height: 24,
borderRadius: 12,
backgroundColor: "rgba(130,4,150, 0.3)",
position: "absolute",
borderWidth: 1,
borderColor: "rgba(130,4,150, 0.5)",
},
cardtitle: {
fontSize: 12,
marginTop: 5,
fontWeight: "bold",
},
cardDescription: {
fontSize: 12,
color: "#444",
},
card: {
elevation: 2,
backgroundColor: "#FFF",
marginHorizontal: 10,
shadowColor: "#000",
shadowRadius: 5,
shadowOpacity: 0.3,
shadowOffset: { x: 2, y: -2 },
height: CARD_HEIGHT,
width: CARD_WIDTH,
overflow: "hidden",
borderRadius: 4,
// height: 210,
// width: 350
},
cardImage: {
flex: 3,
width: "100%",
height: "100%",
alignSelf: "center",
},
textContent: {
flex: 1,
paddingLeft: 4,
paddingRight: 4
},
})
对于SetLocationMap.js
:
render() {
let marker = null;
if(this.state.locationChosen) {
marker = <MapView.Marker coordinate={this.state.focusedLocation} flat={true}/>
}
return(
<View style={this.props.mapContainer}>
{/* <TouchableOpacity onPress={this.getLocationHandler} style={styles.iconContainer}>
<Icon name="md-locate" size={30} color="blue"/>
</TouchableOpacity> */}
<MapView
{...this.props}
style={styles.map}
initialRegion={this.state.focusedLocation}
onPress={this.pickLocationHandler}
ref={ref => this.map = ref} //For animating map movement
>
{marker}
</MapView>
</View>
);
}
const styles = StyleSheet.create({
map: {
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
...StyleSheet.absoluteFillObject
},
iconContainer: {
position: 'absolute',
top: 100,
right: 20,
zIndex: 2,
},
})