如果你想动画改变视图,我想在 RN 中没有直接的方法,但是,在你的情况下,我可以想到一个使用 opacity、position: absolute 和 interpolate() 混合的小技巧,在这里是一个最小的例子,你可以直接复制粘贴来测试它:
import React, { Component } from 'react';
import { StyleSheet, Animated, View, ScrollView } from 'react-native';
class AnimationExample extends Component {
constructor(props) {
super(props)
this.state = {
showBlueView: false,
animatedOpacityValue: new Animated.Value(0),
}
}
handleScroll = (event) => {
const { animatedOpacityValue, showBlueView } = this.state;
const scrollPosition = event.nativeEvent.contentOffset.y;
if (scrollPosition > 100 && !showBlueView) {
Animated.timing(animatedOpacityValue, {
toValue: 1,
}).start(() => this.setState({ showBlueView: true }))
}
if (scrollPosition < 100 && showBlueView) {
Animated.timing(animatedOpacityValue, {
toValue: 0,
}).start(() => this.setState({ showBlueView: false }))
}
}
render() {
const { animatedOpacityValue } = this.state;
return (
<ScrollView
style={styles.scrollView}
onScroll={this.handleScroll}
scrollEventThrottle={16}
>
<View style={styles.green} />
<View style={styles.animatedViewsPositioner}>
<Animated.View
style={{
...styles.red,
opacity: animatedOpacityValue.interpolate({
inputRange: [0, 1],
outputRange: [1, 0],
}),
}}
/>
<Animated.View
style={{
...styles.blue,
opacity: animatedOpacityValue.interpolate({
inputRange: [0, 1],
outputRange: [0, 1],
}),
}}
/>
</View>
</ScrollView>
)
}
}
const styles = StyleSheet.create({
scrollView: {
flex: 1,
},
green: {
height: 600,
width: '100%',
backgroundColor: 'green',
},
red: {
height: 300,
width: '100%',
backgroundColor: 'red',
},
blue: {
position: 'absolute',
height: 300,
width: '100%',
backgroundColor: 'blue',
},
animatedViewsPositioner: {
position: 'relative',
},
})
在上面的示例中,我首先通过将handleScroll 函数应用于scrollView 来访问滚动位置。确保您将 scrollEventThrottle 设置为 16 以确保每秒触发该功能,但请注意可能导致的性能问题(如果您关心,您可以查看 this 以获取更多信息)。
为了实现当用户滚动到某个位置时触发的视图更改(实际上不是,但看起来像那样),我使用view 来包装红色和蓝色视图,红色的默认是@987654330 @,而默认为opacity: 0 的蓝色位于红色的顶部。
我通过使用interpolate() 为opacity 设置动画来隐藏红色视图并显示蓝色视图。借助它,两个不透明度值都由处于状态的一个动画值animatedOpacityValue 控制。我添加了一个状态showBlueView,通过避免不断设置由 onScroll 触发的状态来优化性能。
这是在两个视图上添加touchableOpacities 的更新,只需在未使用时隐藏蓝色视图即可。
首先,添加一个日志功能:
log = (stringToPrint) => () => {
console.log(stringToPrint)
}
接下来,像这样更改scrollView,添加两个touchableOpacity
<ScrollView
style={styles.scrollView}
onScroll={this.handleScroll}
scrollEventThrottle={16}
>
<View style={styles.green} />
<View style={styles.animatedViewsPositioner}>
<Animated.View
style={{
...styles.red,
opacity: animatedOpacityValue.interpolate({
inputRange: [0, 1],
outputRange: [1, 0],
}),
}}
>
<TouchableOpacity
style={{ backgroundColor: 'black', width: 80, height: 30 }}
onPress={this.log('click on red')}
/>
</Animated.View>
{showBlueView && (
<Animated.View
style={{
...styles.blue,
opacity: animatedOpacityValue.interpolate({
inputRange: [0, 1],
outputRange: [0, 1],
}),
}}
>
<TouchableOpacity
style={{ backgroundColor: 'black', width: 80, height: 30 }}
onPress={this.log('click on blue')}
/>
</Animated.View>
)}
</View>
</ScrollView>
注意,我添加了showBlueView &&,当它的不透明度为0时隐藏蓝色视图,这样它就不会阻止任何应用于红色视图的点击事件(即使蓝色视图被隐藏,它实际上是在顶部opacity: 0 的红色视图)。