Skip to content

Instantly share code, notes, and snippets.

@lukebrandonfarrell
Last active January 29, 2024 14:49
Show Gist options
  • Star 13 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save lukebrandonfarrell/866f208718c1326035df4e694c17b2da to your computer and use it in GitHub Desktop.
Save lukebrandonfarrell/866f208718c1326035df4e694c17b2da to your computer and use it in GitHub Desktop.
Collapsable header in React Native
import React, { useRef } from "react";
import { View, Animated, Image, ScrollView, Text } from "react-native";
const H_MAX_HEIGHT = 150;
const H_MIN_HEIGHT = 52;
const H_SCROLL_DISTANCE = H_MAX_HEIGHT - H_MIN_HEIGHT;
const CollapsibleHeader = () => {
const scrollOffsetY = useRef(new Animated.Value(0)).current;
const headerScrollHeight = scrollOffsetY.interpolate({
inputRange: [0, H_SCROLL_DISTANCE],
outputRange: [H_MAX_HEIGHT, H_MIN_HEIGHT],
extrapolate: "clamp"
});
return (
<View style={{ flex: 1 }}>
<ScrollView
onScroll={Animated.event([
{ nativeEvent: { contentOffset: { y: scrollOffsetY } } }
])}
scrollEventThrottle={16}
>
<View style={{ paddingTop: H_MAX_HEIGHT }}>
{/** Page contant goes here **/}
<View style={{ padding: 20 }}>
<Text>React Native Collapsible Header</Text>
</View>
<View style={{ padding: 20, height: 200, backgroundColor: "red" }}>
<Text>View 1</Text>
</View>
<View style={{ padding: 20, height: 200, backgroundColor: "yellow" }}>
<Text>View 1</Text>
</View>
<View style={{ padding: 20, height: 200, backgroundColor: "green" }}>
<Text>View 1</Text>
</View>
</View>
</ScrollView>
{
/**
* We put the header at the bottom of
* our JSX or it will not take priority
* on Android (for some reason, simply
* setting zIndex does not work)
**/
}
<Animated.View
style={{
position: "absolute",
left: 0,
right: 0,
top: 0,
height: headerScrollHeight,
width: "100%",
overflow: "hidden",
zIndex: 999,
// STYLE
borderBottomColor: "#EFEFF4",
borderBottomWidth: 2,
padding: 10,
backgroundColor: "blue"
}}
>
<Image
source={{ uri: "https://via.placeholder.com/300" }}
style={{ flex: 1 }}
resizeMode={"contain"}
/>
</Animated.View>
</View>
)
}
export default CollapsibleHeader;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment