问题
I created a React Native component that consists of 5 icons in a row. The icons are clickable and I want to animate the one that is clicked.
My problem is: When I click an icon, ALL the icons are animated. This is because they are produced in a loop and all given the same properties.
How can I set up my component so that I can somehow only animate the one icon that is pressed?
Here's the component:
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>
);
}
}
Snack: https://snack.expo.io/HJJ0Edhlz
回答1:
@Eric - I'm unable to test this locally, but I'm pretty sure it will do what you want. If it doesn't work out, please let me know and I'll remove my answer.
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>
);
}
}
回答2:
Here you are creating the whole row of icons that's why you face this problem.
Here you have to create one icon at a time rather than creating a row. Like, take a one view for creating a icon and set in one row
<View style = {{flexDirection:'row'}} >
<IconRow />
<IconRow />
<IconRow />
<IconRow />
<IconRow />
</View>
After that, renderIcons function in IconRow class, remove for loop and depended variable 'i' like,
icons.push(
<TouchableHighlight key={1} underlayColor="transparent" onPress={this.onIconPress.bind(this, 1)}>
<AnimatedIcon name="heart" style={{fontSize:this.state.iconFontSize, color: "red"}} />
</TouchableHighlight>
);
or you can iterate for loop only one time like,
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>
);
}
So it creates only one icon at a time and in a row. If you want to give different key than please change '1' to another value.
Now animate the one that is clicked.
Hope It will be helpful.
来源:https://stackoverflow.com/questions/47558958/react-native-only-animate-one-of-several-elements