How to achieve something like CoordinatorLayout in React Native?

android, native, react-native

Solution

The key to reacting to the scroll position fluidly is using `Animated.event` along with the `onScroll` to update an `Animated.value`

getInitialState: function() {
    return {
        scrollY: new Animated.Value(0)
    }
},
render() {
    return (
         <ScrollView
             scrollEventThrottle={16}
             onScroll={Animated.event(
                            [{nativeEvent: 
                               {contentOffset: 
                                 {y: this.state.scrollY}
                               }
                            }]
              )}>
    // etc ...
}

I could then call `interpolate` on `this.state.scrollY` and feed this value into a `transform` style on another component that I wanted to update as the `ScrollView` scrolled.

Problem

I want to achieve a behavior like android's CoordinatorLayout enter always for my ToolBar i tried too many solutions some did work but not fully like https://github.com/maolion/mao-rn-android-kit which is really cool but with one setback as it doesn't work with ListView i also tried Animated but the scroll event throttle on android is just not working most of the times it does not even work. Using mao-rn-android-kit ``` <CoordinatorLayoutAndroid ref={(component) => this.coordinatorLayout = component} fitsSystemWindows={false}> <AppBarLayoutAndroid layoutParams={{ width: 'match_parent', height: 112 }} style={{ backgroundColor:"#528eff" }}> <View layoutParams={{height: 56, width: this.windowWidth, scrollFlags: ( AppBarLayoutAndroid.SCROLL_FLAG_SCROLL | AppBarLayoutAndroid.SCROLL_FLAG_ENTRY_ALWAYS)}} style={{height: 56}}> <ToolbarAndroid titleColor={'#FFF'} title={this.props.title} navIcon={images.arrowBack} onIconClicked={() => this._goBack()} onActionSelected={() => {}} actions={[{title: 'Search', icon: images.search, show: 'always'}]} style={[{backgroundColor: '#528eff', width: this.windowWidth, height: 56}]}/> </View> <View layoutParams={{height: 56, width: this.windowWidth}} style={{flex: 0, flexDirection: 'row', justifyContent: 'center', width: this.windowWidth, backgroundColor: '#528eff'}}> <TouchableOpacity onPress={() => this.getDocuments('high')} style={[styles.highNormalLowDocListHeaderStateTextContainer, highSelected.borderStyle]}> <Text style={[styles.highNormalLowDocListHeaderStateText, highSelected.textStyle]}>HIGH</Text> </TouchableOpacity> <TouchableOpacity onPress={() => this.getDocuments('normal')} style={[styles.highNormalLowDocListHeaderStateTextContainer, normalSelected.borderStyle]}> <Text style={[styles.highNormalLowDocListHeaderStateText, normalSelected.textStyle]}>NORMAL</Text> </TouchableOpacity> <TouchableOpacity onPress={() => this.getDocuments('low')} style={[styles.highNormalLowDocListHeaderStateTextContainer, lowSelected.borderStyle]}> <Text style={[styles.highNormalLowDocListHeaderStateText, lowSelected.textStyle]}>LOW</Text> </TouchableOpacity> </View> </AppBarLayoutAndroid> <View ref={(component) => this.contentLayout = component} style={{flex: 1, backgroundColor: 'transparent', height: this.windowHeight - 150}}> <ListView style={{height: this.windowHeight - 150, overflow: 'hidden'}} dataSource={this.state.documents} enableEmptySections={true} renderRow={(rowData) => this._renderRow(rowData)} /> </View> </CoordinatorLayoutAndroid> ```

Original source