React Native-将屏幕动画化为其MapView.Marker

时间:2019-06-14 07:48:02

标签: javascript react-native react-redux react-native-android react-native-maps

我的目标是在滑动到每个Card(Animated.ScrollView)时,为每个MapView.Marker设置屏幕动画。已经尝试过了,并且可以正常工作,但是现在我对代码做了一些更改,因为我添加了React Redux。

我认为可能是有关指出React Redux状态或密钥的问题,因为我收到有关密钥的警告。它说:

  

警告:列表中的每个孩子都应该有唯一的“关键”道具。

我想为每个MapView.Marker动画屏幕,就像这样:

enter image description here

这是我的代码:

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.props.events.length) {
    index = this.props.events.length - 1;
  } else {
    return null;
  }
  if (index <= 0) {
    index = 0;
  } else {
    return null;
  }

  clearTimeout(this.regionTimeout);
  this.regionTimeout = setTimeout(() => {
    if (this.index !== index) {
      this.index = index;
      const { focusedLocation } = this.props.events.location.value.latitude && this.props.events.location.value.longitude[index];
      this.map.animateToRegion(
        {
          ...focusedLocation,
          latitudeDelta: this.state.focusedLocation.latitudeDelta,
          longitudeDelta: this.state.focusedLocation.longitudeDelta,
        },
        350
      );
    }
  }, 10);
});
}

render() {
//For the Scroll View Card
const interpolations = this.props.events.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}/> */}
    <MapView
      style={styles.container}
      initialRegion={this.state.focusedLocation}
      onPress={this.pickLocationHandler}
      showsUserLocation={true}
      ref={ref => this.map = ref} //For animating map movement
    >
      {userMarker}
      {this.props.events.map((marker, index) => {
        if(marker.location) {
          const scaleStyle = {
            transform: [
              {
                scale: interpolations[index].scale,
              },
            ],
          };
          const opacityStyle = {
            opacity: interpolations[index].opacity,
          };
          return (
            <MapView.Marker key={index} coordinate={marker.location}>
              <Animated.View style={[styles.markerWrap, opacityStyle]}>
                <Animated.View style={[styles.ring, scaleStyle]} />
                  <View style={styles.marker} />
              </Animated.View>
            </MapView.Marker>
          );
        } else {
          return null;
        }
      })}
    </MapView>
    <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 mapStateToProps = state => {
return {
 events: state.events.events
};
};

export default connect(mapStateToProps)(EventMap);

我的React Redux代码:

../../ reducers / events.js:

const reducer = (state = initialState, action) => {
switch (action.type) {
case ADD_EVENT:
  return {
    ...state,
    events: state.events.concat({
      key:  `${Math.random()}`,
      name: action.eventName,
      description: action.eventDescription,
      location: action.location,
      image: {
        uri: "https://c1.staticflickr.com/5/4096/4744241983_34023bf303_b.jpg"
      }
    })
  };

0 个答案:

没有答案