I'm working on an application where I'm trying to Animate a View
based on scroll Position of multiple ScrollView
s.
This is how the screen looks.
The above screen has 2 parts
View
component on Top TabNavigator
component at the Bottomeach tab in TabNavigator
has a ScrollView
in it (in this case there are 2 but can be more), What I want to achieve is to collapse the View
as the user scrolls down and expand it when the user scrolls up. On a single Tab I was doing well, it was working exactly how I wanted it to do, but the problem came when I added the 2nd Tab.
The Problem
When I scroll a bit on tab1 and move to tab2 and try to scroll, it gets jerky. see the GIF to understand what I'm trying to say
Check this snack on expo.io to see the problem live
snack.expo.io/SytBkdBAW
What I tried
App.js
export default class App extends Component { constructor (props) { super(props) this.state = { /* omitted - not related */ scrollY: new Animated.Value(0) } } render () { let translateY = this.state.scrollY.interpolate({ inputRange: [0, 600], outputRange: [0, -290], extrapolate: 'clamp' }); let TabsTranslateY = this.state.scrollY.interpolate({ inputRange: [0, 600], outputRange: [0, -290], extrapolate: 'clamp' }); return ( <View style={styles.container}> <Animated.View style={{transform: [{translateY: translateY}], overflow: 'hidden'}}> <Text style={styles.welcome}> Welcome to React Native!! </Text> <Text style={styles.time}> {this.state.hour} : {this.state.minute} </Text> <TouchableOpacity onPress={() => { /* omitted */ }} style={styles.button}><Text style={styles.buttonText}>Set Time</Text></TouchableOpacity> </Animated.View> <Animated.View style={{ flex: 0, transform: [{translateY: TabsTranslateY}], height: Dimensions.get('window').height }}> <Tabs removeClippedSubviews={false} screenProps={{animatedScrollY: this.state.scrollY}}/> </Animated.View> </View> ) } } const styles = StyleSheet.create({/* omitted styles*/})
Home.js (Tab1)
/* omitted imports */ export default class Home extends Component { /* omitted navigation options */ constructor (props) { super(props) this.state = { scrollY: this.props.screenProps.animatedScrollY } } render () { return ( <View> <Animated.ScrollView onScroll={Animated.event( [{nativeEvent: {contentOffset: {y: this.state.scrollY}}}], {useNativeDriver: true} )} scrollEventThrottle={16}> {Array(90).fill().map((v, i) => { return <Text key={i} style={{flex: 1, backgroundColor: '#333', padding: 20, marginVertical: 10, color: 'white'}}>Item #{i + 1}</Text> })} </Animated.ScrollView> </View> ) } }
Photos.js (Tab2)
/* omitted imports */ export default class Photos extends Component { /* omitted navigation options */ constructor (props) { super(props) this.state = { PhotosScrollY: this.props.screenProps.animatedScrollY } } render () { return ( <Animated.ScrollView onScroll={Animated.event( [{nativeEvent: {contentOffset: {y: this.state.PhotosScrollY}}}], {useNativeDriver: true} )} scrollEventThrottle={16}> <View style={{flex: 1,}}> {Array(90).fill().map((v, i) => { return <View key={i} style={/* omitted */}> <Text style={/* omitted */}> Photo #{i + 1} </Text> </View> })} </View> </Animated.ScrollView> ) } }
I'm not sure how to overcome this problem, Any suggestions and solutions are appreciated.
Thanks.
Try to use Animated.add()
So you need in App
const tab1ScrollY = new Animated.Value(0) const tab2ScrollY = new Animated.Value(0) const scrollY = Animated.add(tab1ScrollY,tab2ScrollY)
scrollY
it's offset of tab1 scroll
+ tab2 scroll
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With