为什么 react-native Animated View 不渲染?
Why is react-native Animated View not rendering?
目标:创建一个主按钮,当按下该按钮时,它会沿 Z 轴旋转 180 度,并启动次要选项按钮的不透明度和平移(Y 轴)动画,这些按钮在按下主按钮时显示。然后逆向整个过程折叠二级选项。
MainButton 实现:
import React from 'react';
import { StyleSheet, View, Dimensions } from 'react-native';
import Component from './Component';
const optionsArr = [
{ icon: require('./src/assets/img/chat.png'), onPress: () => alert('option 1') },
{ icon: require('./src/assets/img/video_icon.png'), onPress: () => alert('option 2') },
{ icon: require('./src/assets/img/voice_icon.png'), onPress: () => alert('option 3') },
{ icon: require('./src/assets/img/camera.png'), onPress: () => alert('option 4') }
];
const App = () => {
return (
<View style={styles.screen}>
<Component icon={require('./src/assets/img/arrow-up.png')} optionItems={optionsArr} />
</View>
);
};
const styles = StyleSheet.create({
screen: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#E6E6E6'
}
});
export default App;
MainButton.js:
import React, { useState, useEffect } from 'react';
import { Image, Animated, StyleSheet, TouchableOpacity, Dimensions } from 'react-native';
import EStyleSheet from 'react-native-extended-stylesheet';
import OptionItemBtn from './OptionItemBtn';
const { height, width } = Dimensions.get('window');
const MainButton = (props) => {
const [ animatedHeight ] = useState(new Animated.Value(0));
const [ animatedRotate ] = useState(new Animated.Value(0));
const [ expanded, setExpanded ] = useState(false);
const handlePress = () => {
if (expanded) {
// button is opened
let collapseHeight = 0.00000001;
Animated.parallel([
Animated.spring(animatedHeight, {
toValue: collapseHeight
}),
Animated.spring(animatedRotate, {
toValue: 0
})
]).start();
setExpanded(!expanded);
} else {
// button is collapsed
Animated.parallel([
Animated.spring(animatedHeight, {
toValue: width * 0.13 * props.optionItems.length
}),
Animated.spring(animatedRotate, {
toValue: 1
})
]).start();
}
};
const animatedRotation = animatedRotate.interpolate({
inputRange: [ 0, 0.5, 1 ],
outputRange: [ '0deg', '90deg', '180deg' ]
});
return (
<Animated.View style={{ transform: [ { rotateZ: animatedRotation } ] }}>
<Animated.View style={{ transform: [ { translateY: animatedHeight } ] }}>
{props.optionItems.map((item, index) => {
<OptionItemBtn icon={item.icon} onPress={item.onPress} index={index} />;
})}
</Animated.View>
<TouchableOpacity style={styles.container} onPress={() => handlePress()}>
<Image resizeMode={'contain'} source={props.icon} style={styles.icon} />
</TouchableOpacity>
</Animated.View>
);
};
const styles = StyleSheet.create({
container: {
justifyContent: 'center',
alignItems: 'center',
borderRadius: 30,
backgroundColor: '#E06363',
elevation: 15,
shadowOffset: {
height: 3,
width: 3
},
shadowColor: '#333',
shadowOpacity: 0.5,
shadowRadius: 5,
height: width * 0.14,
width: width * 0.14
},
icon: {
height: width * 0.06,
width: width * 0.06
}
});
export default MainButton;
OptionItem.js:
import React from 'react';
import { Image, StyleSheet, TouchableOpacity, Dimensions } from 'react-native';
const { height, width } = Dimensions.get('window');
const OptionItemBtn = (props) => {
return (
<TouchableOpacity style={styles.container} onPress={props.onPress}>
<Image resizeMode={'contain'} source={props.icon} style={styles.icon} />
</TouchableOpacity>
);
};
const styles = StyleSheet.create({
container: {
justifyContent: 'center',
alignItems: 'center',
borderRadius: 30,
backgroundColor: '#219F75',
elevation: 5,
shadowOffset: {
height: 3,
width: 3
},
shadowColor: '#333',
shadowOpacity: 0.5,
shadowRadius: 5,
height: width * 0.13,
width: width * 0.13,
position: 'absolute'
},
icon: {
height: width * 0.08,
width: width * 0.08
}
});
export default OptionItemBtn;
问题:主按钮按预期显示和动画。它在展开和折叠时沿 Z 轴正确旋转。问题是 OptionItemBtn 根本不呈现。为什么?
{props.optionItems.map((item, index) =>
<OptionItemBtn icon={item.icon} onPress={item.onPress} index={index} />
)}
在您的 MainButton.js 文件中进行上述更改
目标:创建一个主按钮,当按下该按钮时,它会沿 Z 轴旋转 180 度,并启动次要选项按钮的不透明度和平移(Y 轴)动画,这些按钮在按下主按钮时显示。然后逆向整个过程折叠二级选项。
MainButton 实现:
import React from 'react';
import { StyleSheet, View, Dimensions } from 'react-native';
import Component from './Component';
const optionsArr = [
{ icon: require('./src/assets/img/chat.png'), onPress: () => alert('option 1') },
{ icon: require('./src/assets/img/video_icon.png'), onPress: () => alert('option 2') },
{ icon: require('./src/assets/img/voice_icon.png'), onPress: () => alert('option 3') },
{ icon: require('./src/assets/img/camera.png'), onPress: () => alert('option 4') }
];
const App = () => {
return (
<View style={styles.screen}>
<Component icon={require('./src/assets/img/arrow-up.png')} optionItems={optionsArr} />
</View>
);
};
const styles = StyleSheet.create({
screen: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#E6E6E6'
}
});
export default App;
MainButton.js:
import React, { useState, useEffect } from 'react';
import { Image, Animated, StyleSheet, TouchableOpacity, Dimensions } from 'react-native';
import EStyleSheet from 'react-native-extended-stylesheet';
import OptionItemBtn from './OptionItemBtn';
const { height, width } = Dimensions.get('window');
const MainButton = (props) => {
const [ animatedHeight ] = useState(new Animated.Value(0));
const [ animatedRotate ] = useState(new Animated.Value(0));
const [ expanded, setExpanded ] = useState(false);
const handlePress = () => {
if (expanded) {
// button is opened
let collapseHeight = 0.00000001;
Animated.parallel([
Animated.spring(animatedHeight, {
toValue: collapseHeight
}),
Animated.spring(animatedRotate, {
toValue: 0
})
]).start();
setExpanded(!expanded);
} else {
// button is collapsed
Animated.parallel([
Animated.spring(animatedHeight, {
toValue: width * 0.13 * props.optionItems.length
}),
Animated.spring(animatedRotate, {
toValue: 1
})
]).start();
}
};
const animatedRotation = animatedRotate.interpolate({
inputRange: [ 0, 0.5, 1 ],
outputRange: [ '0deg', '90deg', '180deg' ]
});
return (
<Animated.View style={{ transform: [ { rotateZ: animatedRotation } ] }}>
<Animated.View style={{ transform: [ { translateY: animatedHeight } ] }}>
{props.optionItems.map((item, index) => {
<OptionItemBtn icon={item.icon} onPress={item.onPress} index={index} />;
})}
</Animated.View>
<TouchableOpacity style={styles.container} onPress={() => handlePress()}>
<Image resizeMode={'contain'} source={props.icon} style={styles.icon} />
</TouchableOpacity>
</Animated.View>
);
};
const styles = StyleSheet.create({
container: {
justifyContent: 'center',
alignItems: 'center',
borderRadius: 30,
backgroundColor: '#E06363',
elevation: 15,
shadowOffset: {
height: 3,
width: 3
},
shadowColor: '#333',
shadowOpacity: 0.5,
shadowRadius: 5,
height: width * 0.14,
width: width * 0.14
},
icon: {
height: width * 0.06,
width: width * 0.06
}
});
export default MainButton;
OptionItem.js:
import React from 'react';
import { Image, StyleSheet, TouchableOpacity, Dimensions } from 'react-native';
const { height, width } = Dimensions.get('window');
const OptionItemBtn = (props) => {
return (
<TouchableOpacity style={styles.container} onPress={props.onPress}>
<Image resizeMode={'contain'} source={props.icon} style={styles.icon} />
</TouchableOpacity>
);
};
const styles = StyleSheet.create({
container: {
justifyContent: 'center',
alignItems: 'center',
borderRadius: 30,
backgroundColor: '#219F75',
elevation: 5,
shadowOffset: {
height: 3,
width: 3
},
shadowColor: '#333',
shadowOpacity: 0.5,
shadowRadius: 5,
height: width * 0.13,
width: width * 0.13,
position: 'absolute'
},
icon: {
height: width * 0.08,
width: width * 0.08
}
});
export default OptionItemBtn;
问题:主按钮按预期显示和动画。它在展开和折叠时沿 Z 轴正确旋转。问题是 OptionItemBtn 根本不呈现。为什么?
{props.optionItems.map((item, index) =>
<OptionItemBtn icon={item.icon} onPress={item.onPress} index={index} />
)}
在您的 MainButton.js 文件中进行上述更改