In many applications you see a Collapsible toolbar or a specific section on the app screen that collapsible when you scroll up.
So, in this article we will learn how to create this type of collapsible section in React Native app. And at last there is a complete source code given with which you can directly create a collapsible section in your app.
Add import statements
import React from 'react';
import {
View,
Text,
Animated,
Platform,
StyleSheet,
ScrollView,
} from 'react-native';
First add the height of the collapsible view below the import statements
const Header_Maximum_Height = 200;
//Maximum height of the collapsible view.
const Header_Minimum_Height = 50;
//Minimum height of the collapsible view.
Initialize header animation in constructor
constructor(props) {
super(props);
this.AnimatedHeaderValue = new Animated.Value(0);
this.state = {};
}
Add animation config inside the render
const AnimateHeaderBackgroundColor = this.AnimatedHeaderValue.interpolate({
inputRange: [0, Header_Maximum_Height - Header_Minimum_Height],
outputRange: ['#4286F4', '#00BCD4'],
extrapolate: 'clamp',
});
const AnimateHeaderHeight = this.AnimatedHeaderValue.interpolate({
inputRange: [0, Header_Maximum_Height - Header_Minimum_Height],
outputRange: [Header_Maximum_Height, Header_Minimum_Height],
extrapolate: 'clamp',
});
Now, add the header view and other content on the screen.
<View style={styles.container}>
<Animated.View
style={[
styles.header,
{
height: headerHeightAnim,
backgroundColor: headerBackColorAnim,
},
]}>
<Text style={styles.headerText}>Countries</Text>
</Animated.View>
<ScrollView
scrollEventThrottle={16}
contentContainerStyle={{paddingTop: headerMaxHeight}}
onScroll={Animated.event(
[{nativeEvent: {contentOffset: {y: this.headerAnim}}}],
{},
)}>
{/* Put all your Component here inside the ScrollView */}
<Text style={styles.TextViewStyle}>India</Text>
<Text style={styles.TextViewStyle}>Australia</Text>
<Text style={styles.TextViewStyle}>New Zealand</Text>
<Text style={styles.TextViewStyle}>Brazil</Text>
<Text style={styles.TextViewStyle}>Japan</Text>
<Text style={styles.TextViewStyle}>Uganda</Text>
<Text style={styles.TextViewStyle}>Indonesia</Text>
<Text style={styles.TextViewStyle}>Hungary</Text>
<Text style={styles.TextViewStyle}>Switzerland</Text>
<Text style={styles.TextViewStyle}>Sweden</Text>
<Text style={styles.TextViewStyle}>Germany</Text>
<Text style={styles.TextViewStyle}>Finland</Text>
<Text style={styles.TextViewStyle}>France</Text>
<Text style={styles.TextViewStyle}>South Africa</Text>
<Text style={styles.TextViewStyle}>Denmark</Text>
<Text style={styles.TextViewStyle}>Peru</Text>
<Text style={styles.TextViewStyle}>Colombia</Text>
</ScrollView>
</View>
Add styles at bottom with using StyleSheet.create
const styles = StyleSheet.create({
container: {
flex: 1,
paddingTop: Platform.OS == 'ios' ? 20 : 0,
},
header: {
justifyContent: 'center',
alignItems: 'center',
position: 'absolute',
left: 0,
right: 0,
top: Platform.OS == 'ios' ? 20 : 0,
},
headerText: {
color: '#fff',
fontSize: 18,
textAlign: 'center',
},
textStyle: {
textAlign: 'center',
color: '#000',
fontSize: 18,
margin: 5,
padding: 7,
},
});
Complete source code
import React from 'react';
import {
View,
Text,
Animated,
Platform,
StyleSheet,
ScrollView,
} from 'react-native';
const headerMaxHeight = 200;
const headerMinHeight = 50;
export default class LoginScreen extends React.Component {
constructor(props) {
super(props);
this.headerAnim = new Animated.Value(0);
this.state = {};
}
render() {
const headerBackColorAnim = this.headerAnim.interpolate({
inputRange: [0, headerMaxHeight - headerMinHeight],
outputRange: ['#4286F4', '#00BCD4'],
extrapolate: 'clamp',
useNativeDriver: true,
});
const headerHeightAnim = this.headerAnim.interpolate({
inputRange: [0, headerMaxHeight - headerMinHeight],
outputRange: [headerMaxHeight, headerMinHeight],
extrapolate: 'clamp',
useNativeDriver: true,
});
return (
<View style={styles.container}>
<Animated.View
style={[
styles.header,
{
height: headerHeightAnim,
backgroundColor: headerBackColorAnim,
},
]}>
<Text style={styles.headerText}>Countries</Text>
</Animated.View>
<ScrollView
scrollEventThrottle={16}
contentContainerStyle={{paddingTop: headerMaxHeight}}
onScroll={Animated.event(
[{nativeEvent: {contentOffset: {y: this.headerAnim}}}],
{},
)}>
{/* Put all your Component here inside the ScrollView */}
<Text style={styles.textStyle}>India</Text>
<Text style={styles.textStyle}>Australia</Text>
<Text style={styles.textStyle}>New Zealand</Text>
<Text style={styles.textStyle}>Brazil</Text>
<Text style={styles.textStyle}>Japan</Text>
<Text style={styles.textStyle}>Uganda</Text>
<Text style={styles.textStyle}>Indonesia</Text>
<Text style={styles.textStyle}>Hungary</Text>
<Text style={styles.textStyle}>Switzerland</Text>
<Text style={styles.textStyle}>Sweden</Text>
<Text style={styles.textStyle}>Germany</Text>
<Text style={styles.textStyle}>Finland</Text>
<Text style={styles.textStyle}>France</Text>
<Text style={styles.textStyle}>South Africa</Text>
<Text style={styles.textStyle}>Denmark</Text>
<Text style={styles.textStyle}>Peru</Text>
<Text style={styles.textStyle}>Colombia</Text>
</ScrollView>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
paddingTop: Platform.OS == 'ios' ? 20 : 0,
},
header: {
justifyContent: 'center',
alignItems: 'center',
position: 'absolute',
left: 0,
right: 0,
top: Platform.OS == 'ios' ? 20 : 0,
},
headerText: {
color: '#fff',
fontSize: 18,
textAlign: 'center',
},
textStyle: {
textAlign: 'center',
color: '#000',
fontSize: 18,
margin: 5,
padding: 7,
},
});
Output