我对 React Native 中的动画 API 相当陌生。我浏览了很多使用动画 API 的教程,似乎每个教程中的元素都是绝对定位的,是否有必要将元素绝对定位?
我还制作了一段动画,但它看起来有问题,我认为文本输入后的 View 没有绝对位置,这可能会导致问题。是否可以在保持文本输入位置绝对但其他元素使用 Flexbox 定位的同时执行我尝试的动画?
这是代码
handleFocus = () => {
console.log('starting animation');
this.setState({
isFocused: true
});
Animated.timing(this.isFromViewFocused, {
toValue: 1,
duration: 300
}).start();
}
handleBlur = () => {
console.log('Blurring');
this.setState({
isFocused: false
});
Animated.timing(this.isFromViewFocused, {
toValue: 0,
duration: 300
}).start();
}
render() {
const labelStyle = {
position: this.state.isFocused === true ? 'absolute' : 'relative',
alignItems: 'center',
width: this.isFromViewFocused.interpolate({
inputRange: [0, 1],
outputRange: [DEVICE_WIDTH * 0.45, DEVICE_WIDTH]
}),
left: this.isFromViewFocused.interpolate({
inputRange: [0, 1],
outputRange: [DEVICE_WIDTH * 0.03, 0]
}),
marginBottom: this.isFromViewFocused.interpolate({
inputRange: [0, 1],
outputRange: [0, 80]
}),
top: this.isFromViewFocused.interpolate({
inputRange: [0, 1],
outputRange: [10, 0]
}),
borderWidth: this.isFromViewFocused.interpolate({
inputRange: [0, 1],
outputRange: [0, 5]
}),
borderColor: 'black',
paddingTop: this.state.isFocused === true ? 20 : 0
};
return (
<View style={styles.container}>
<ScrollView style={{ flex: 1 }} keyboardDismissMode='on-drag'>
<Animated.View
style={labelStyle}
>
<TextInput
onFocus={this.handleFocus}
onBlur={this.handleBlur}
style={{
borderColor: 'black',
borderWidth: 1,
width: '90%'
}}
>
<Text>Hey Text</Text>
</TextInput>
</Animated.View>
<Animated.View
style={[styles.LocationContainer,
{ marginTop: this.isFromViewFocused.interpolate({
inputRange: [0, 1],
outputRange: [20, 80]
})
}
]}>
最佳答案
使用绝对
定位与left
、top
、bottom
、right
相结合对表演不利。这就是为什么你的动画看起来“有问题”。
您最好使用转换,以便您的组件保持相对
并且可以进行 native 优化(与 CSS3 转换相同)。
此外,当使用非 native 优化属性(例如您使用的属性)时,您无法将 useNativeDriver
设置为 true。这使得性能变得更差。
补充一点,您不能(或不应该)基于 bool 值进行插值。 AnimatedJS 为您提供了一个 Animated.Value 类,旨在使插入内容变得更容易。
这是一个更简单的动画示例:
export class MyAnimatedComponent extends React.Component {
state = {
animatedValue: new Animated.Value(0);
}
focus = () => {
const { animatedValue } = this.state;
Animated.timing(animatedValue, {
duration: 280,
toValue: 1,
// This will make your animation glitch-free/performant.
useNativeDriver: true,
}).start();
}
blur = () => {
Animated.timing(animatedValue, {
duration: 140,
toValue: 0,
// This will make your animation glitch-free/performant.
useNativeDriver: true,
}).start();
}
render () {
const { animatedValue } = this.state;
const animatedStyles = {
transform: [
{
// Move the div by 120px to the left when value === 1
translateX: animatedValue.interpolate({
inputRange: [0, 1],
outputRange: [0, -120],
// Tells Animated to never go outside of the outputRange
extrapolate: 'clamp',
})
},
{
translateY: animatedValue.interpolate({
inputRange: [0, 1],
outputRange: [0, -50],
extrapolate: 'clamp',
})
}
]
}
return (
<View style={styles.wrapper}>
<Animated.View style={animatedStyles} onFocus={onFocus} onBlur={onBlur}>
I'm some content into an Animated div.
</Animated.View>
</View>
)
}
}
关于javascript - 在 React Native 中正确使用动画 API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53723521/