I want to achieve this animation using section list on scroll in react native.
Here is an example of food panda. This is their initial screen:

On scrolling the section list their header collapse and it becomes like this:

Here is the code of my RestaurantDetail screen:
export default function RestaurantDetail({navigation, route}) {
const headerHeight = 400;
const headerFinalHeight = 100;
const scrollY = useRef(new Animated.Value(0)).current;
const offset = headerHeight - headerFinalHeight;
const translateHeader = scrollY.interpolate({
inputRange: [0, offset],
outputRange: [0, -offset],
extrapolate: 'clamp',
});
useEffect(() => {
return navigation.addListener('focus', () => {
getRestaurantDetail();
if (user) {
getCart();
}
});
}, []);
const onScrollY = e => {
scrollY.setValue(e.nativeEvent.contentOffset.y);
headerHeight - e.nativeEvent.contentOffset.y;
console.log('Height', scrollY);
};
const onScroll = ({viewableItems}) => {
setActiveTab(viewableItems[0].section.title);
console.log('viewableItems', viewableItems[0].section.title);
};
return (
<View style={{backgroundColor: 'white', flex: 1}}>
<Animated.View
style={{
backgroundColor: 'white',
height: headerHeight,
position: 'absolute',
transform: [{translateY: translateHeader}],
}}>
<Header restaurantDetail={detail} />
<View style={{flexDirection: 'row', justifyContent: 'space-between'}}>
<MainImage restaurantDetail={detail} />
<TouchableOpacity
onPress={() => navigation.navigate('RestaurantInfo', detail)}>
<Rating />
</TouchableOpacity>
</View>
<TouchableOpacity
onPress={() => navigation.navigate('RestaurantInfo', detail)}>
<Title restaurantDetail={detail} />
</TouchableOpacity>
<HeaderTabs
activeTab={activeTab}
setActiveTab={setActiveTab}
data={itemList}
ref={ref}
/>
</Animated.View>
<View style={{paddingTop: headerHeight}}>
<SectionListeg
restaurantDetail={detail}
activeTab={activeTab}
setActiveTab={setActiveTab}
navigation={navigation}
onScroll={onScroll}
onScrollY={onScrollY}
data={itemList}
scrollEventThrottle={16}
/>
</View>
{showView && (
<View style={styles.box}>
<View style={styles.viewCartView}>
<TouchableOpacity
activeOpacity={0.7}
onPress={() => navigation.navigate('Cart', true)}>
<View style={styles.viewCartBtn}>
<View style={styles.counterView}>
<Text style={styles.text}>
{cart.cart ? cart.cart.length : cart.length}
</Text>
</View>
<Text style={styles.text}>View your cart</Text>
<Text style={styles.text}>{'Rs. ' + cart.sub_total}</Text>
</View>
</TouchableOpacity>
</View>
</View>
)}
<SafeAreaView
style={{
position: 'absolute',
top: 0,
left: 0,
right: 0,
backgroundColor: transparent ? 'transparent' : 'white',
}}>
<TopBar navigation={navigation} shouldShow={shouldShow} name={name} />
</SafeAreaView>
</View>
);
}
const styles = StyleSheet.create({
viewCartView: {
width: '100%',
height: 100,
backgroundColor: 'white',
position: 'absolute',
bottom: 0,
borderTopRightRadius: 10,
borderTopLeftRadius: 10,
alignItems: 'center',
justifyContent: 'center',
elevation: 5,
},
headerContainer: {
// position: 'absolute',
},
box: {
// ...
shadowColor: '#000',
shadowOffset: {width: 0, height: 2},
shadowOpacity: 1.0,
shadowRadius: 3,
elevation: 5,
},
viewCartBtn: {
width: '90%',
height: 50,
backgroundColor: Colors.secondary,
alignSelf: 'center',
borderRadius: 10,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-evenly',
},
counterView: {
width: 30,
height: 30,
borderRadius: 50,
borderWidth: 1.5,
borderColor: 'white',
justifyContent: 'center',
alignItems: 'center',
},
text: {color: 'white', fontSize: 16, fontWeight: '700'},
});
Here is the code of my Section List:
const SectionListeg = ({
navigation,
onScroll,
data,
scrollEventThrottle,
activeTab,
onScrollY,
setIndex,
setActiveTab,
restaurantDetail,
shouldShow,
branchId,
}) => {
const headerHeight = 400;
const headerFinalHeight = 100;
const offset = headerHeight - headerFinalHeight;
const scrollY = useRef(new Animated.Value(0)).current;
const translateHeader = scrollY.interpolate({
inputRange: [0, offset],
outputRange: [0, -offset],
extrapolate: 'clamp',
});
const renderItem = ({item, index}) => {
return (
<Item
item={item}
navigation={navigation}
restaurantDetail={restaurantDetail}
/>
);
};
return (
<SectionList
sections={data}
showsVerticalScrollIndicator={false}
scrollEnabled={true}
keyExtractor={(item, index) => {
// console.log('Key Index', item.title);
if (item.id) {
return item.id;
}
}}
renderItem={renderItem}
onViewableItemsChanged={onScroll}
onScroll={onScrollY}
stickySectionHeadersEnabled={false}
renderSectionHeader={({section: {title}}) => (
<Text style={styles.header}>{title}</Text>
)}
/>
);
};
const Item = ({item, navigation, restaurantDetail}) => (
<View style={styles.item}>
<TouchableOpacity
activeOpacity={0.7}
style={{flexDirection: 'row', width: '100%'}}
onPress={() => onItemPress(item, navigation, restaurantDetail)}>
<View style={{flexDirection: 'row'}}>
<View style={{width: '70%'}}>
<Text style={styles.title}>{item.title}</Text>
<Text numberOfLines={2} style={styles.description}>
{item.description}
</Text>
<Text style={{marginTop: 5, color: Colors.black}}>
PKR {item.price}
</Text>
</View>
<View style={{width: '30%'}}>
<Image
style={styles.image}
source={{uri: 'https://uat.yallafood.pk/' + item.imageUrl}}
/>
</View>
</View>
<View
style={{
width: '100%',
height: 1,
position: 'absolute',
bottom: 0,
left: 0,
backgroundColor: Colors.grey,
}}
/>
</TouchableOpacity>
</View>
);
const styles = StyleSheet.create({
container: {
flex: 1,
marginHorizontal: 16,
},
item: {
backgroundColor: '#fff',
marginVertical: 5,
paddingStart: 20,
paddingEnd: 20,
flexDirection: 'row',
justifyContent: 'space-between',
},
header: {
fontSize: 26,
backgroundColor: '#fff',
marginLeft: 20,
fontWeight: 'bold',
color: 'black',
},
title: {
fontSize: 20,
color: 'black',
},
description: {
fontSize: 14,
color: Colors.grey,
marginTop: 5,
// width: '50%',
},
image: {
width: 80,
height: 80,
borderRadius: 10,
marginBottom: 10,
alignSelf: 'flex-end',
},
});
Any help will be appreciated.

