I would need an animation as shown in this video: https://youtu.be/1vt3uCq_Y1g?si=9Z0RaJRRqrMt5ICn
The general animation is as such: When you start to scroll the list, the header collapses with nice smooth animation from current height to fixed min height based on scrolling list’s scroll value and sticks on the top of the screen
However, this implementation shown in the video is with scroll view but i need it to render my items in a flatlist. How can i change the animations? I am working on android platform only
really similar like ScrollViews, here is an example
import React, { useRef } from 'react';
import {
StyleSheet,
View,
Text,
ScrollView,
TextInput,
Animated,
TouchableOpacity,
Image,
} from 'react-native';
import FeatherIcon from 'react-native-vector-icons/Feather';
import FontAwesome from 'react-native-vector-icons/FontAwesome5';
const items = [
{
img: 'https://images.unsplash.com/photo-1518684079-3c830dcef090?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=987&q=80',
name: 'Dubai',
airport: 'DXB',
departure: '2022-10-10',
arrival: '2023-04-01',
price: 966,
},
{
img: 'https://images.unsplash.com/photo-1516483638261-f4dbaf036963?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=986&q=80',
name: 'Italy',
airport: 'VCE',
departure: '2022-10-10',
arrival: '2023-04-01',
price: 652,
},
{
img: 'https://images.unsplash.com/photo-1623536167776-922ccb1ff749?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=544&q=80',
name: 'Bosnia',
airport: 'BNX',
departure: '2022-10-10',
arrival: '2023-04-01',
price: 566,
},
{
img: 'https://images.unsplash.com/photo-1554939437-ecc492c67b78?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=987&q=80',
name: 'Spain',
airport: 'BCN',
departure: '2022-10-10',
arrival: '2023-04-01',
price: 602,
},
];
export default function Example() {
const scrollY = useRef(new Animated.Value(0)).current;
const translateHeader = scrollY.interpolate({
inputRange: [0, 80],
outputRange: [0, -80],
extrapolate: 'clamp',
});
const opacityTitle = scrollY.interpolate({
inputRange: [0, 50],
outputRange: [1, 0],
extrapolate: 'clamp',
});
const translateTitle = scrollY.interpolate({
inputRange: [0, 80],
outputRange: [0, 40],
extrapolate: 'clamp',
});
return (
<View style={{ backgroundColor: '#05141c' }}>
<Animated.View
style={[
styles.header,
{ transform: [{ translateY: translateHeader }] },
]}>
<Animated.Text
style={[
styles.headerTitle,
{ opacity: opacityTitle },
,
{ transform: [{ translateY: translateTitle }] },
]}>
Cheap flights{'\n'}to anywhere
</Animated.Text>
<View style={styles.inputWrapper}>
<TextInput
placeholder="Where are you going?"
placeholderTextColor="#05141c"
style={styles.input}
/>
<View style={styles.inputIcon}>
<FeatherIcon color="#05141c" name="search" size={16} />
</View>
</View>
</Animated.View>
<Animated.FlatList
contentContainerStyle={styles.content}
onScroll={Animated.event(
[{ nativeEvent: { contentOffset: { y: scrollY } } }],
{
useNativeDriver: true,
}
)}
data={items}
scrollEventThrottle={1}
renderItem={(
{ item: { img, name, airport, departure, arrival, price } },
index
) => {
return (
<View key={index} style={{ opacity: 0.25 }}>
<TouchableOpacity
onPress={() => {
// handle onPress
}}>
<View style={styles.card}>
<Image
alt=""
resizeMode="cover"
source={{ uri: img }}
style={styles.cardImg}
/>
<View style={styles.cardBody}>
<Text>
<Text style={styles.cardTitle}>{name}</Text>{' '}
<Text style={styles.cardAirport}>{airport}</Text>
</Text>
<View style={styles.cardRow}>
<View style={styles.cardRowItem}>
<FontAwesome
color="#6f61c4"
name="plane-departure"
size={10}
/>
<Text style={styles.cardRowItemText}>
{new Date(departure).toLocaleDateString('en-US', {
day: 'numeric',
month: 'short',
year: 'numeric',
})}
</Text>
</View>
<View style={styles.cardRowItem}>
<FontAwesome
color="#6f61c4"
name="plane-arrival"
size={10}
/>
<Text style={styles.cardRowItemText}>
{new Date(arrival).toLocaleDateString('en-US', {
day: 'numeric',
month: 'short',
year: 'numeric',
})}
</Text>
</View>
</View>
<Text style={styles.cardPrice}>
<Text>from </Text>
<Text style={styles.cardPriceValue}>
${price?.toLocaleString('en-US')}{' '}
</Text>
<Text style={styles.cardPriceCurrency}>USD</Text>
</Text>
<TouchableOpacity
onPress={() => {
// handle onPress
}}>
<View style={styles.btn}>
<Text style={styles.btnText}>Book now</Text>
</View>
</TouchableOpacity>
</View>
</View>
</TouchableOpacity>
</View>
);
}}
/>
</View>
);
}
const styles = StyleSheet.create({
content: {
padding: 24,
paddingTop: 212,
backgroundColor: '#fff',
},
header: {
position: 'absolute',
width: '100%',
zIndex: 1,
paddingHorizontal: 24,
paddingVertical: 12,
height: 200,
alignItems: 'stretch',
justifyContent: 'flex-end',
backgroundColor: '#05141c',
},
headerTitle: {
fontSize: 26,
lineHeight: 34,
fontWeight: 'bold',
color: '#fff',
textAlign: 'center',
marginBottom: 12,
},
input: {
height: 44,
backgroundColor: '#fff',
paddingLeft: 44,
paddingRight: 24,
borderRadius: 12,
fontSize: 15,
fontWeight: '500',
color: '#222',
},
inputWrapper: {
position: 'relative',
width: '100%',
},
inputIcon: {
position: 'absolute',
width: 44,
height: 44,
top: 0,
left: 0,
bottom: 0,
alignItems: 'center',
justifyContent: 'center',
},
card: {
flexDirection: 'row',
alignItems: 'stretch',
borderRadius: 12,
marginBottom: 16,
backgroundColor: '#fff',
},
cardImg: {
width: 120,
height: 154,
borderRadius: 12,
},
cardBody: {
flexGrow: 1,
flexShrink: 1,
flexBasis: 0,
flexDirection: 'column',
justifyContent: 'space-between',
alignItems: 'flex-start',
paddingVertical: 8,
paddingHorizontal: 16,
},
cardTitle: {
fontSize: 22,
fontWeight: '700',
color: '#173153',
marginRight: 8,
},
cardAirport: {
fontSize: 13,
fontWeight: '600',
color: '#5f697d',
},
cardRow: {
flexDirection: 'row',
alignItems: 'center',
marginHorizontal: -8,
flexWrap: 'wrap',
},
cardRowItem: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
paddingHorizontal: 6,
},
cardRowItemText: {
marginLeft: 4,
fontSize: 12,
fontWeight: '500',
color: '#5f697d',
},
cardPrice: {
fontSize: 13,
fontWeight: '500',
color: '#5f697d',
},
cardPriceValue: {
fontSize: 21,
fontWeight: '700',
color: '#173153',
},
cardPriceCurrency: {
fontSize: 14,
fontWeight: 'bold',
color: '#6f61c4',
},
btn: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
borderRadius: 8,
paddingVertical: 6,
paddingHorizontal: 14,
borderWidth: 1,
backgroundColor: '#173153',
borderColor: '#173153',
},
btnText: {
fontSize: 13,
lineHeight: 18,
fontWeight: '600',
color: '#fff',
},
});