React Native:只为几个元素中的一个设置动画

时间:2017-11-29 17:59:08

标签: javascript animation react-native

我创建了一个React Native组件,它由一行中的5个图标组成。 图标是可点击的,我想为点击的图标设置动画。

我的问题是:点击图标后,所有图标都会动画显示。这是因为它们是在循环中生成的,并且都具有相同的属性。

如何设置我的组件,以便我可以以某种方式仅为按下的一个图标设置动画?

这是组件:

import React from 'react';
import { StyleSheet, Animated, View, Text, TouchableHighlight, } from 'react-native';
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
const AnimatedIcon = Animated.createAnimatedComponent(Icon);

export class IconRow extends React.Component {  

  constructor(props) {
    super(props);
    this.state = { iconFontSize: new Animated.Value(50) };
  }

  onIconPress = (index) => {
    Animated.sequence([
      Animated.timing(this.state.iconFontSize, { toValue: 40, duration: 100 }),
      Animated.timing(this.state.iconFontSize, { toValue: 58, duration: 100 }),
      Animated.timing(this.state.iconFontSize, { toValue: 50, duration: 100 }),
    ]).start();
  }

  renderIcons() {
    var icons = [];
    for (var i = 0; i < 5; i++) {
      icons.push(
        <TouchableHighlight key={i} underlayColor="transparent" onPress={this.onIconPress.bind(this, i)}>       
          <AnimatedIcon name="heart" style={{fontSize:this.state.iconFontSize, color: "red"}} />
        </TouchableHighlight>   
      );        
    }
    return icons;
  }

  render() {
    return (
        <View style={{flexDirection: "row"}}>
          {this.renderIcons()}
        </View>
    );
  }
}

小吃:https://snack.expo.io/HJJ0Edhlz

2 个答案:

答案 0 :(得分:2)

在这里,您要创建整行图标,这就是您遇到此问题的原因。

在这里,您必须一次创建一个图标,而不是创建一行。 比如,创建一个图标并在一行中设置一个视图

<View style = {{flexDirection:'row'}} >
    <IconRow />
    <IconRow />
    <IconRow />
    <IconRow />
    <IconRow />
</View>

之后,在IconRow类中使用renderIcons函数,删除for循环并依赖变量&#39; i&#39;等,

icons.push(
        <TouchableHighlight key={1} underlayColor="transparent" onPress={this.onIconPress.bind(this, 1)}>       
          <AnimatedIcon name="heart" style={{fontSize:this.state.iconFontSize, color: "red"}} />
        </TouchableHighlight> 
);

或者你可以只循环迭代一次,如

for (var i = 0; i < 1; i++) {
      icons.push(
        <TouchableHighlight key={1} underlayColor="transparent" onPress={this.onIconPress.bind(this, 1)}>       
          <AnimatedIcon name="heart" style={{fontSize:this.state.iconFontSize, color: "red"}} />
        </TouchableHighlight> 
      );
}

因此它一次只能创建一个图标。如果您想提供不同的密钥,请更改&#39; 1&#39;另一个值。

现在为点击的动画制作动画。

希望它会有所帮助。

答案 1 :(得分:2)

@Eric - 我无法在本地测试,但我很确定它会做你想要的。如果它没有成功,请告诉我,我将删除我的答案。

import React from 'react';
import { StyleSheet, Animated, View, Text, TouchableHighlight, } from 'react-native';
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
const AnimatedIcon = Animated.createAnimatedComponent(Icon);

export class IconRow extends React.Component {  

  constructor(props) {
    super(props);
    this.state = { 
      iconFontSizes: [
        new Animated.Value(50),
        new Animated.Value(50),
        new Animated.Value(50),
        new Animated.Value(50),
        new Animated.Value(50)
      ], 
    };
  }

  onIconPress = (i) => {
    Animated.sequence([
      Animated.timing(this.state.iconFontSizes[i], { toValue: 40, duration: 100 }),
      Animated.timing(this.state.iconFontSizes[i], { toValue: 58, duration: 100 }),
      Animated.timing(this.state.iconFontSizes[i], { toValue: 50, duration: 100 }),
    ]).start();
  }

  renderIcons() {
    var icons = [];

    for (var i = 0; i < this.state.iconFontSizes.length; i++) {
      icons.push(
        <TouchableHighlight key={i} underlayColor="transparent" onPress={this.onIconPress.bind(this, i)}>       
          <AnimatedIcon name="heart" style={{fontSize:this.state.iconFontSizes[i], color: "red"}} />
        </TouchableHighlight>   
      );        
    }

    return icons;
  }

  render() {
    return (
        <View style={{flexDirection: "row"}}>
          {this.renderIcons()}
        </View>
    );
  }
}