React Native通过Map动态添加动画

时间:2017-10-15 17:00:07

标签: react-native

我很难搞清楚为什么我无法在卡片组中添加简单的动画。我想在每次按下按钮时为单张卡制作动画。我能够在一张卡上实现这一点,但在第二次渲染后,动画不再适用。我正在使用setState跟踪按钮按下和一些逻辑,以将Animated.View应用于列表中的下一张卡片上。所以在我看来,当应用程序第一次运行时,显示卡片中的所有卡片,用户按下按钮,第一张卡片被移除,依此类推第四张。

export default class Cards extends React.Component {
  componentWillMount() {
    this.animatedValue = new Animated.ValueXY(0, 0);
  }
  state = { index: 0 };

  renderCards = () => {
    console.log("App started");
    const { data } = this.props;
    return data.map((cards, idx) => {
      if (idx < this.state.index) {
        return null;
      }

      if (idx === this.state.index) {
        console.log("animated being added to " + idx);
        console.log(` the state is  ${this.state.index} in renderCards `);
        return (
          <View>
            <Animated.View style={[this.animatedValue.getLayout()]}>
              <Card>
                <Text>Animated Value</Text>
              </Card>
            </Animated.View>
          </View>
        );
      }

      return (
        <View>
          <Card>
            <Text>No Animation</Text>
          </Card>
        </View>
      );
    });
  };
  nextCard = () => {
    Animated.spring(this.animatedValue, {
      toValue: { x: 500, y: 0 }
    }).start();
    this.setState({ index: this.state.index + 1 });
  };
  render() {
    return (
      <View style={styles.cardContainer}>
        {this.renderCards()}
        <Button
          large
          icon={{ name: "envira", type: "font-awesome" }}
          title="Press me"
          style={styles.button}
          onPress={() => this.nextCard()}
        />
      </View>
    );
  }
}

第二次渲染两张牌消失但我不明白为什么会发生这种情况。

我不确定我做错了什么。

感谢。

1 个答案:

答案 0 :(得分:1)

主要问题是动画值(this.animatedValue)未重置。

'活动卡'的渲染视图(其中idx === this.state.index)固定为this.animatedValue的值。您需要在动画后将此值重置为0,0。现在,它保持在x:500,y:0并且将下一张牌呈现在屏幕外(消失)。

我会在动画回调中更新你的nextCard函数:

nextCard = () => {
  Animated.spring(this.animatedValue, {
    toValue: { x: 500, y: 0 },
  }).start(() => {
    this.animatedValue = new Animated.ValueXY(0, 0);
    this.setState({ index: this.state.index + 1 });
  });
};

请注意,更新animatedValue和设置状态的顺序与状态一样重要,会触发重新渲染。