-
Notifications
You must be signed in to change notification settings - Fork 44
Expand file tree
/
Copy pathFlatList.tsx
More file actions
103 lines (92 loc) · 3.16 KB
/
FlatList.tsx
File metadata and controls
103 lines (92 loc) · 3.16 KB
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
import React, { useCallback, useMemo } from 'react';
import { ListRenderItem, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { useNavigation } from '@react-navigation/native';
import {
Header,
LargeHeader,
ScalingView,
ScrollHeaderProps,
ScrollLargeHeaderProps,
FlatListWithHeaders,
} from '@codeherence/react-native-header';
import { range } from '../../utils';
import { Avatar, BackButton } from '../../components';
import { RANDOM_IMAGE_NUM } from '../../constants';
import type { FlatListUsageScreenNavigationProps } from '../../navigation';
const HeaderComponent: React.FC<ScrollHeaderProps> = ({ showNavBar }) => {
const navigation = useNavigation();
const onPressProfile = () => navigation.navigate('Profile');
return (
<Header
showNavBar={showNavBar}
headerCenter={
<Text style={styles.navBarTitle} numberOfLines={1}>
Header
</Text>
}
headerRight={
<>
<TouchableOpacity onPress={onPressProfile}>
<Avatar
size="sm"
source={{ uri: `https://i.pravatar.cc/128?img=${RANDOM_IMAGE_NUM}` }}
/>
</TouchableOpacity>
</>
}
headerRightFadesIn
headerLeft={<BackButton />}
/>
);
};
const LargeHeaderComponent: React.FC<ScrollLargeHeaderProps> = ({ scrollY }) => {
const navigation = useNavigation();
const onPressProfile = () => navigation.navigate('Profile');
return (
<LargeHeader>
<ScalingView scrollY={scrollY} style={styles.leftHeader}>
<Text style={styles.title}>Large Header</Text>
</ScalingView>
<TouchableOpacity onPress={onPressProfile}>
<Avatar size="sm" source={{ uri: `https://i.pravatar.cc/128?img=${RANDOM_IMAGE_NUM}` }} />
</TouchableOpacity>
</LargeHeader>
);
};
// Used for FlatList optimization
const ITEM_HEIGHT = 60;
const FlatList: React.FC<FlatListUsageScreenNavigationProps> = () => {
const { bottom } = useSafeAreaInsets();
const data = useMemo(() => range({ end: 500 }), []);
const renderItem: ListRenderItem<number> = useCallback(({ item }) => {
return (
<View style={styles.item}>
<Text style={styles.itemText}>{item}. Scroll to see header animation</Text>
</View>
);
}, []);
return (
<FlatListWithHeaders
HeaderComponent={HeaderComponent}
LargeHeaderComponent={LargeHeaderComponent}
contentContainerStyle={{ paddingBottom: bottom }}
data={data}
renderItem={renderItem}
windowSize={10}
automaticallyAdjustsScrollIndicatorInsets={false}
getItemLayout={(_, index) => ({ index, length: ITEM_HEIGHT, offset: index * ITEM_HEIGHT })}
initialNumToRender={50}
maxToRenderPerBatch={100}
keyExtractor={(_, i) => `text-row-${i}`}
/>
);
};
export default FlatList;
const styles = StyleSheet.create({
navBarTitle: { fontSize: 16, fontWeight: 'bold' },
title: { fontSize: 32, fontWeight: 'bold' },
leftHeader: { gap: 2 },
item: { minHeight: ITEM_HEIGHT, padding: 16, justifyContent: 'center', alignItems: 'center' },
itemText: { textAlign: 'center' },
});