Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Animating a single View based on multiple ScrollView(s)

I'm working on an application where I'm trying to Animate a View based on scroll Position of multiple ScrollViews.

This is how the screen looks.

Profile Screen

The above screen has 2 parts

  • A View component on Top
  • A TabNavigator component at the Bottom

each 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

React Native Animation Jerk


Update

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.

like image 758
Azeem Hassni Avatar asked Oct 27 '17 16:10

Azeem Hassni


Video Answer


1 Answers

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

like image 84
Oleksandr Cherniavenko Avatar answered Sep 22 '22 22:09

Oleksandr Cherniavenko