Collapsible Expandable Animated Header is a type of application header(Title Bar-Action bar) used to automatically expandable when user scrolls down the ScrollView and also it would automatically Collapsible when user scrolls up inside the application. So in this tutorial we would going to create a react native app with Collapsible Expandable Animated Header on ScrollView in both Android and iOS applications and we would also change the Header background color when user scrolls down or scrolls up. See the below .GIF file to know how this header would work .
Screenshot :
Content in this project Collapsible Expandable Animated Header on ScrollView in React Native app :
1. Import ScrollView, StyleSheet, View, Animated, Text and Platform component in your project.
1
2
3
|
import React, { Component } from ‘react’;
import { ScrollView, StyleSheet, View,Animated, Text, Platform } from ‘react-native’;
|
2. Create 2 constant variables named as Header_Maximum_Height and Header_Minimum_Height.
Header_Maximum_Height : This is the Maximum height of animated header.
Header_Minimum_Height : This is the minimum height of animated header.
1
2
3
4
5
6
7
|
import React, { Component } from ‘react’;
import { ScrollView, StyleSheet, View,Animated, Text, Platform } from ‘react-native’;
const Header_Maximum_Height = 200;
const Header_Minimum_Height = 50;
|
3. Create constructor() in your project’s class. Now we would create a animated value object using this.AnimatedHeaderValue and assign the animated value to zero.
1
2
3
4
5
6
7
|
constructor()
{
super();
this.AnimatedHeaderValue = new Animated.Value(0);
}
|
4. Create a const in render’s block named as AnimateHeaderBackgroundColor and assign the this.AnimatedHeaderValue.interpolate method on it. This block of code is used to smoothly change the background color of Header when user scrolls up or scrolls down.
extrapolate: ‘clamp’ : Is used to stop the animation beyond the output defined range.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
render()
{
const AnimateHeaderBackgroundColor = this.AnimatedHeaderValue.interpolate(
{
inputRange: [ 0, ( Header_Maximum_Height – Header_Minimum_Height ) ],
outputRange: [ ‘#009688’, ‘#00BCD4’ ],
extrapolate: ‘clamp’
});
return(
);
}
|
5. Create another const named as AnimateHeaderHeight in render’s block and assign the this.AnimatedHeaderValue.interpolate method on it. This block of code is used to animated the Header height when user scrolls down or scrolls up.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
render()
{
const AnimateHeaderBackgroundColor = this.AnimatedHeaderValue.interpolate(
{
inputRange: [ 0, ( Header_Maximum_Height – Header_Minimum_Height ) ],
outputRange: [ ‘#009688’, ‘#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’
});
return(
);
}
|
6. Create a Root View in render’s return block. This would be our main View.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
render()
{
const AnimateHeaderBackgroundColor = this.AnimatedHeaderValue.interpolate(
{
inputRange: [ 0, ( Header_Maximum_Height – Header_Minimum_Height ) ],
outputRange: [ ‘#009688’, ‘#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’
});
return(
<View style = { styles.MainContainer }>
</View>
);
}
|
7. Create a ScrollView component inside the Root View and call the Animated.event method on onScroll event. I am also adding 20 Text boxes in ScrollView just to explain how it will work. You can put your own component inside the ScrollView.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
render()
{
const AnimateHeaderBackgroundColor = this.AnimatedHeaderValue.interpolate(
{
inputRange: [ 0, ( Header_Maximum_Height – Header_Minimum_Height ) ],
outputRange: [ ‘#009688’, ‘#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’
});
return(
<View style = { styles.MainContainer }>
<ScrollView
scrollEventThrottle = { 16 }
contentContainerStyle = {{ paddingTop: Header_Maximum_Height }}
onScroll = { Animated.event(
[{ nativeEvent: { contentOffset: { y: this.AnimatedHeaderValue }}}]
)}>
{/* Put all your Component here inside the ScrollView */}
<Text style={styles. TextViewStyle}>Sample Text 1</Text>
<Text style={styles. TextViewStyle}>Sample Text 2</Text>
<Text style={styles. TextViewStyle}>Sample Text 3</Text>
<Text style={styles. TextViewStyle}>Sample Text 4</Text>
<Text style={styles. TextViewStyle}>Sample Text 5</Text>
<Text style={styles. TextViewStyle}>Sample Text 6</Text>
<Text style={styles. TextViewStyle}>Sample Text 7</Text>
<Text style={styles. TextViewStyle}>Sample Text 8</Text>
<Text style={styles. TextViewStyle}>Sample Text 9</Text>
<Text style={styles. TextViewStyle}>Sample Text 10</Text>
<Text style={styles. TextViewStyle}>Sample Text 11</Text>
<Text style={styles. TextViewStyle}>Sample Text 12</Text>
<Text style={styles. TextViewStyle}>Sample Text 13</Text>
<Text style={styles. TextViewStyle}>Sample Text 14</Text>
<Text style={styles. TextViewStyle}>Sample Text 15</Text>
<Text style={styles. TextViewStyle}>Sample Text 16</Text>
<Text style={styles. TextViewStyle}>Sample Text 17</Text>
<Text style={styles. TextViewStyle}>Sample Text 18</Text>
<Text style={styles. TextViewStyle}>Sample Text 19</Text>
<Text style={styles. TextViewStyle}>Sample Text 20</Text>
{/* Put all your Component here inside the ScrollView */}
</ScrollView>
</View>
);
}
|
8. Creating Animated.View component after ScrollView closed. This would be our Animated Header View. We are also creating a Text component inside the Animated View.
1
2
3
4
5
|
<Animated.View style = {[ styles.HeaderStyle, { height: AnimateHeaderHeight, backgroundColor: AnimateHeaderBackgroundColor } ]}>
<Text style={styles.HeaderInsideTextStyle}> Collapsible Expandable Header </Text>
</Animated.View>
|
9. Create CSS style classes for Root View, Animated header and header inside Text and all common Text boxes.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
const styles = StyleSheet.create(
{
MainContainer:
{
flex: 1,
paddingTop: (Platform.OS == ‘ios’) ? 20 : 0
},
HeaderStyle:
{
justifyContent: ‘center’,
alignItems: ‘center’,
position: ‘absolute’,
left: 0,
right: 0,
top: (Platform.OS == ‘ios’) ? 20 : 0,
},
HeaderInsideTextStyle:
{
color: “#fff”,
fontSize: 18,
textAlign: ‘center’
},
TextViewStyle:
{
textAlign: ‘center’,
color: “#000”,
fontSize: 18,
margin: 5,
padding: 7,
backgroundColor: “#ECEFF1”
}
});
|
10. Complete source code for App.js File :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
|
import React, { Component } from ‘react’;
import { ScrollView, StyleSheet, View,Animated, Text, Platform } from ‘react-native’;
const Header_Maximum_Height = 200;
const Header_Minimum_Height = 50;
export default class Mynewproject extends Component<{}>
{
constructor()
{
super();
this.AnimatedHeaderValue = new Animated.Value(0);
}
render()
{
const AnimateHeaderBackgroundColor = this.AnimatedHeaderValue.interpolate(
{
inputRange: [ 0, ( Header_Maximum_Height – Header_Minimum_Height ) ],
outputRange: [ ‘#009688’, ‘#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’
});
return(
<View style = { styles.MainContainer }>
<ScrollView
scrollEventThrottle = { 16 }
contentContainerStyle = {{ paddingTop: Header_Maximum_Height }}
onScroll = { Animated.event(
[{ nativeEvent: { contentOffset: { y: this.AnimatedHeaderValue }}}]
)}>
{/* Put all your Component here inside the ScrollView */}
<Text style={styles. TextViewStyle}>Sample Text 1</Text>
<Text style={styles. TextViewStyle}>Sample Text 2</Text>
<Text style={styles. TextViewStyle}>Sample Text 3</Text>
<Text style={styles. TextViewStyle}>Sample Text 4</Text>
<Text style={styles. TextViewStyle}>Sample Text 5</Text>
<Text style={styles. TextViewStyle}>Sample Text 6</Text>
<Text style={styles. TextViewStyle}>Sample Text 7</Text>
<Text style={styles. TextViewStyle}>Sample Text 8</Text>
<Text style={styles. TextViewStyle}>Sample Text 9</Text>
<Text style={styles. TextViewStyle}>Sample Text 10</Text>
<Text style={styles. TextViewStyle}>Sample Text 11</Text>
<Text style={styles. TextViewStyle}>Sample Text 12</Text>
<Text style={styles. TextViewStyle}>Sample Text 13</Text>
<Text style={styles. TextViewStyle}>Sample Text 14</Text>
<Text style={styles. TextViewStyle}>Sample Text 15</Text>
<Text style={styles. TextViewStyle}>Sample Text 16</Text>
<Text style={styles. TextViewStyle}>Sample Text 17</Text>
<Text style={styles. TextViewStyle}>Sample Text 18</Text>
<Text style={styles. TextViewStyle}>Sample Text 19</Text>
<Text style={styles. TextViewStyle}>Sample Text 20</Text>
{/* Put all your Component here inside the ScrollView */}
</ScrollView>
<Animated.View style = {[ styles.HeaderStyle, { height: AnimateHeaderHeight, backgroundColor: AnimateHeaderBackgroundColor } ]}>
<Text style={styles.HeaderInsideTextStyle}> Collapsible Expandable Header </Text>
</Animated.View>
</View>
);
}
}
const styles = StyleSheet.create(
{
MainContainer:
{
flex: 1,
paddingTop: (Platform.OS == ‘ios’) ? 20 : 0
},
HeaderStyle:
{
justifyContent: ‘center’,
alignItems: ‘center’,
position: ‘absolute’,
left: 0,
right: 0,
top: (Platform.OS == ‘ios’) ? 20 : 0,
},
HeaderInsideTextStyle:
{
color: “#fff”,
fontSize: 18,
textAlign: ‘center’
},
TextViewStyle:
{
textAlign: ‘center’,
color: “#000”,
fontSize: 18,
margin: 5,
padding: 7,
backgroundColor: “#ECEFF1”
}
});
|
Screenshot in Android device :