Slide 9 import React from 'react'; import { FlatList, Text, View, StyleSheet } from 'react-native'; const ContactsScreen = () => { // 1. data: Масив об'єктів const contacts = [ { id: '1', name: 'Олександр', phone: '+380970000001' }, { id: '2', name: 'Марія', phone: '+380500000002' }, { id: '3', name: 'Дмитро', phone: '+380630000003' }, ]; // 2. renderItem: Як виглядає один рядок списку const renderContact = ({ item }) => ( {item.name} {item.phone} ); return ( item.id} // Унікальний ключ contentContainerStyle={styles.container} /> ); }; const styles = StyleSheet.create({ container: { padding: 20 }, item: { padding: 15, borderBottomWidth: 1, borderBottomColor: '#ccc', }, name: { fontWeight: 'bold', fontSize: 18 }, }); export default ContactsScreen; Slide 11 import React from 'react'; import { FlatList, View, Text, StyleSheet } from 'react-native'; const MyApp = () => { const data = [ { id: '1', title: 'Перший елемент' }, { id: '2', title: 'Другий елемент' }, { id: '3', title: 'Третій елемент' }, ]; // 1. Створюємо окремий компонент для лінії const MySeparator = () => ( ); const renderItem = ({ item }) => ( {item.title} ); return ( item.id} ItemSeparatorComponent={MySeparator} /> ); }; const styles = StyleSheet.create({ item: { padding: 20 }, text: { fontSize: 16 }, }); export default MyApp; Slide 12 import React, { useState } from 'react'; import { FlatList, View, Text, StyleSheet } from 'react-native'; const MyListScreen = () => { const [items, setItems] = useState([ { id: '1', title: 'Елемент №1' }, { id: '2', title: 'Елемент №2' }, { id: '3', title: 'Елемент №3' }, ]); const renderItem = ({ item }) => ( {item.title} ); return ( item.id} ItemSeparatorComponent={() => ( )} ListEmptyComponent={ Список порожній } contentContainerStyle={{ flexGrow: 1 }} /> ); }; const styles = StyleSheet.create({ item: { padding: 20, backgroundColor: '#fff', }, text: { fontSize: 16, }, emptyContainer: { flex: 1, justifyContent: 'center', alignItems: 'center', }, }); export default MyListScreen; Slide 14 import React, { useState } from 'react'; import { FlatList, View, Text, StyleSheet} from 'react-native'; const MyAdvancedList = () => { const [data, setData] = useState([ { id: '1', title: 'Елемент 1' }, { id: '2', title: 'Елемент 2' }, { id: '3', title: 'Елемент 3' }, ]); const renderHeader = () => ( Header ); const renderFooter = () => ( Footer ); const renderSeparator = () => ( ); return ( item.id} renderItem={({ item }) => ( {item.title} )} ListHeaderComponent={renderHeader} ListFooterComponent={renderFooter} ItemSeparatorComponent={renderSeparator} /> ); }; const styles = StyleSheet.create({ header: { padding: 20, backgroundColor: '#f0f0f0', alignItems: 'center' }, headerText: { fontWeight: 'bold', fontSize: 18 }, footer: { padding: 10, backgroundColor: '#eee', alignItems: 'center' }, footerText: { color: 'gray' }, item: { padding: 25, backgroundColor: 'white' }, itemText: { fontSize: 16 }, empty: { flex: 1, textAlign: 'center', textAlignVertical: 'center', marginTop: 50 } }); export default MyAdvancedList; Slide 15 import React from 'react'; import { FlatList, Text, View, StyleSheet } from 'react-native'; const SimpleList = () => { const data = [{ id: '1', title: 'Елемент 1' }, { id: '2', title: 'Елемент 2' }]; return ( item.id} renderItem={({ item }) => ( {item.title} )} // 1. СТИЛЬ "ВІКНА" style={styles.externalStyle} // 2. СТИЛЬ ВНУТРІШНЬОГО ВМІСТУ (Контейнер з елементами) contentContainerStyle={styles.internalContainer} /> ); }; const styles = StyleSheet.create({ externalStyle: { marginTop: 50, borderWidth: 2, borderColor: 'blue', // Синя рамка покаже межі самого FlatList height: 300, // Обмежимо висоту "вікна" }, internalContainer: { padding: 20, backgroundColor: '#f9f9f9', }, card: { padding: 20, backgroundColor: '#fff', marginBottom: 10, borderWidth: 1, } }); export default SimpleList; Slide 16 import React from 'react'; import { FlatList, View, Text, StyleSheet, SafeAreaView } from 'react-native'; const HorizontalScroll = () => { const categories = [ { id: '1', name: 'Гаджети' }, { id: '2', name: 'Взуття' }, { id: '3', name: 'Книги' }, { id: '4', name: 'Дім' }, { id: '5', name: 'Спорт' }, ]; return ( item.id} // 1. Робимо список горизонтальним horizontal={true} // 2. ПРИХОВУЄМО скролбар showsHorizontalScrollIndicator={false} contentContainerStyle={styles.listPadding} renderItem={({ item }) => ( {item.name} )} /> ); }; const styles = StyleSheet.create({ container: { backgroundColor: '#fff', }, listPadding: { paddingHorizontal: 10, paddingVertical: 20, }, chip: { backgroundColor: '#e0e0e0', paddingHorizontal: 20, paddingVertical: 10, marginHorizontal: 5, borderRadius: 20, }, }); export default HorizontalScroll; Slide 17 import React from 'react'; import { FlatList, View, Text, StyleSheet, SafeAreaView } from 'react-native'; const numColumns = 2; // Кількість колонок const GridExample = () => { const data = [ { id: '1', title: 'Товар 1' }, { id: '2', title: 'Товар 2' }, { id: '3', title: 'Товар 3' }, { id: '4', title: 'Товар 4' }, ]; const renderItem = ({ item }) => ( {item.title} ); return ( item.id} // numColumns={numColumns} contentContainerStyle={styles.listContent} /> ); }; const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#fff',paddingTop: 10 }, listContent: { padding: 10 }, item: { backgroundColor: '#4CAF50', alignItems: 'center', justifyContent: 'center', flex: 1, // Важливо: flex дозволяє елементам розтягуватися порівну margin: 5, // Відступи між колонками height: 150, // Вимагає фіксованої або контрольованої висоти borderRadius: 8, }, itemText: { color: '#fff', fontWeight: 'bold' }, }); export default GridExample; Slide 18 import React, { useState, useEffect } from 'react'; import { FlatList, View, Text, ActivityIndicator, StyleSheet, SafeAreaView } from 'react-native'; const InfiniteList = () => { const [data, setData] = useState([]); const [isLoading, setIsLoading] = useState(false); const [page, setPage] = useState(1); const [hasMore, setHasMore] = useState(true); // Імітація запиту до API const fetchItems = async (currentPage) => { if (isLoading || !hasMore) return; setIsLoading(true); // Імітуємо затримку мережі setTimeout(() => { const newData = Array.from({ length: 15 }, (_, i) => ({ id: `${currentPage}-${i}`, title: `Елемент сторінки ${currentPage}, №${i + 1}`, })); // 1. Immutability: створюємо новий масив на основі старого setData(prevData => [...prevData, ...newData]); // Імітуємо кінець даних на 5-й сторінці if (currentPage >= 5) setHasMore(false); setPage(currentPage + 1); setIsLoading(false); }, 1500); }; useEffect(() => { fetchItems(1); // Перше завантаження }, []); // 2. Footer: показуємо лоадер, тільки якщо є що завантажувати const renderFooter = () => { if (!isLoading) return null; return ( ); }; return ( item.id} // renderItem={({ item }) => ( {item.title} )} // КЛЮЧОВІ ПРОПСИ ДЛЯ ПАГІНАЦІЇ onEndReached={() => fetchItems(page)} // Виклик при наближенні до кінця onEndReachedThreshold={0.5} // Поріг: 0.5 означає "за половину екрана до кінця" ListFooterComponent={renderFooter} // Індикатор завантаження внизу ItemSeparatorComponent={() => } // contentContainerStyle={{ flexGrow: 1 }} // /> ); }; const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#fff' }, item: { padding: 25, backgroundColor: '#fff' }, separator: { height: 1, backgroundColor: '#eee' }, footer: { paddingVertical: 20, alignItems: 'center' }, }); export default InfiniteList; Slide 19 import React, { useState } from 'react'; import { FlatList, View, Text, StyleSheet, TouchableOpacity, SafeAreaView } from 'react-native'; const DynamicGrid = () => { const [columns, setColumns] = useState(2); const data = Array.from({ length: 10 }, (_, i) => ({ id: i.toString(), name: `Об'єкт ${i + 1}` })); // Функція для перемикання сітки const toggleColumns = () => { setColumns(prev => (prev === 2 ? 3 : 2)); }; return ( Змінити на {columns === 2 ? '3' : '2'} колонки item.id} // contentContainerStyle={styles.listContent} // renderItem={({ item }) => ( {item.name} )} /> ); }; const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#fff', paddingTop: 10 }, button: { backgroundColor: '#007AFF', padding: 15, margin: 10, borderRadius: 8, alignItems: 'center', }, buttonText: { color: '#fff', fontWeight: 'bold' }, listContent: { padding: 5 }, item: { flex: 1, // Елементи ділять ширину порівну margin: 5, backgroundColor: '#333', justifyContent: 'center', alignItems: 'center', borderRadius: 10, }, itemText: { color: '#fff' }, }); export default DynamicGrid; Slide 20 import React, { useState } from 'react'; import { FlatList, View, Text, StyleSheet, SafeAreaView } from 'react-native'; const SmoothPagination = () => { const [data, setData] = useState(Array.from({ length: 20 }, (_, i) => ({ id: i.toString(), name: `Елемент ${i + 1}` }))); const loadMoreData = () => { console.log("Починаємо підвантаження заздалегідь..."); // Логіка додавання даних: [...oldData, ...newData] const nextItems = Array.from({ length: 20 }, (_, i) => ({ id: (data.length + i).toString(), name: `Елемент ${data.length + i + 1}` })); setData([...data, ...nextItems]); }; return ( item.id} // renderItem={({ item }) => ( {item.name} )} // --- НАЛАШТУВАННЯ ПЛАВНОСТІ --- // Функція спрацює, коли до кінця залишиться рівно 1 висота екрану скролу. // Це рекомендоване значення для того, щоб користувач взагалі не бачив лоадера. onEndReachedThreshold={1} onEndReached={loadMoreData} // Розділювач для візуальної чистоти ItemSeparatorComponent={() => } /> ); }; const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#fff' }, item: { padding: 50, alignItems: 'center', backgroundColor: '#fff' }, separator: { height: 1, backgroundColor: '#eee' } }); export default SmoothPagination; Slide 21 import React, { useState } from 'react'; import { FlatList, View, Text, StyleSheet, SafeAreaView } from 'react-native'; // Початкові дані const INITIAL_DATA = [ { id: '1', title: 'Новина 1: React Native оновився' }, { id: '2', title: 'Новина 2: Вийшов новий iPhone' }, { id: '3', title: 'Новина 3: Курс біткоїна змінився' }, ]; export default function App() { const [news, setNews] = useState(INITIAL_DATA); const [refreshing, setRefreshing] = useState(false); // --- ФУНКЦІЯ ОНОВЛЕННЯ --- const handleRefresh = () => { // 1. Вмикаємо спінер setRefreshing(true); // 2. Імітуємо запит до API (чекаємо 2 секунди) setTimeout(() => { // 3. Додаємо "свіжу" новину на початок списку const newArticle = { id: Date.now().toString(), title: `🔥 Свіжа новина (${new Date().toLocaleTimeString()})`, }; setNews(prevNews => [newArticle, ...prevNews]); // 4. Вимикаємо спінер setRefreshing(false); }, 2000); }; return ( item.id} refreshing={refreshing} onRefresh={handleRefresh} renderItem={({ item }) => ( {item.title} )} tintColor="#2196F3" /> ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#f0f0f0', paddingTop: 50 }, card: { backgroundColor: 'white', padding: 20, marginVertical: 8, marginHorizontal: 16, borderRadius: 10, shadowColor: '#000', shadowOpacity: 0.1, shadowRadius: 5, elevation: 3, }, text: { fontSize: 16, fontWeight: '500' }, }); Slide 22 import React from 'react'; import { FlatList, Text, View } from 'react-native'; const data = [ { id: '1', title: '1. Я перший у коді' }, { id: '2', title: '2. Я другий' }, { id: '3', title: '3. Я третій' }, ]; export default function App() { return ( item.id} inverted renderItem={({ item }) => ( {item.title} )} /> ); } Slide 24 import React, { useRef } from 'react'; import { View, Text, FlatList, TouchableOpacity, StyleSheet } from 'react-native'; // Генеруємо масив із 100 елементів const DATA = Array.from({ length: 100 }, (_, i) => ({ id: i, title: `Елемент ${i}` })); const ITEM_HEIGHT = 60; // Фіксована висота елемента export default function App() { const flatListRef = useRef(null); const scroll = (index, position) => { flatListRef.current?.scrollToIndex({ index: index, animated: true, viewPosition: position, }); }; return ( item.id.toString()} getItemLayout={(data, index) => ({ length: ITEM_HEIGHT, offset: ITEM_HEIGHT * index, index, })} renderItem={({ item }) => ( {item.title} )} /> scroll(10, 0)} > ID 10{'\n'}Вгору (0) scroll(50, 0.5)} > ID 50{'\n'}Центр (0.5) scroll(90, 1)} > ID 90{'\n'}Вниз (1) ); } const styles = StyleSheet.create({ container: { flex: 1, paddingTop: 50 }, item: { height: ITEM_HEIGHT, justifyContent: 'center', paddingLeft: 20, borderBottomWidth: 1, borderBottomColor: '#ccc', }, highlight: { backgroundColor: '#ffebee' }, text: { fontSize: 18 }, buttonsContainer: { flexDirection: 'row', justifyContent: 'space-around', padding: 10, backgroundColor: '#eee', borderTopWidth: 1, borderColor: '#ddd' }, btn: { backgroundColor: '#2196f3', padding: 10, borderRadius: 8, alignItems: 'center' }, btnText: { color: 'white', fontWeight: 'bold', textAlign: 'center', fontSize: 12 } }); Slide 25 import React, { useRef } from 'react'; import { View, Text, FlatList, TouchableOpacity, StyleSheet, Alert } from 'react-native'; // Генеруємо дані з різною довжиною тексту (різна висота) const DATA = Array.from({ length: 100 }, (_, i) => ({ id: i, title: `Item ${i}`, description: i % 2 === 0 ? 'Короткий опис.' : 'Це довгий опис елемента, який займає більше місця на екрані, щоб висота була динамічною і ми могли протестувати scrollToIndexFailed.' })); export default function App() { const flatListRef = useRef(null); const scrollToIndex = (index) => { // 1. Спроба скролу (може викликати помилку, якщо елемент далеко) flatListRef.current?.scrollToIndex({ index: index, animated: true, viewPosition: 0.5, // Центр }); }; return ( scrollToIndex(80)} > Go to ID 80 item.id.toString()} onScrollToIndexFailed={(info) => { console.log('⚠️ Елемента немає в памʼяті. Виконуємо план Б...'); const wait = new Promise(resolve => setTimeout(resolve, 500)); // Крок 1: Скролимо до ПРИБЛИЗНОЇ позиції // info.averageItemLength — це середня висота вже відрендерених елементів const offset = info.index * info.averageItemLength; flatListRef.current?.scrollToOffset({ offset: offset, animated: true, }); // Крок 2: Чекаємо рендеру і коригуємо (Retry) wait.then(() => { flatListRef.current?.scrollToIndex({ index: info.index, animated: true, viewPosition: 0.5, }); }); }} renderItem={({ item }) => ( {item.title} {item.description} )} /> ); } const styles = StyleSheet.create({ container: { flex: 1, paddingTop: 50 }, header: { padding: 10, borderBottomWidth: 1, borderColor: '#ccc', alignItems: 'center' }, btn: { backgroundColor: '#6200ee', padding: 10, borderRadius: 8 }, btnText: { color: 'white', fontWeight: 'bold' }, item: { padding: 20, borderBottomWidth: 1, borderBottomColor: '#eee', backgroundColor: 'white' }, targetItem: { backgroundColor: '#ffeb3b', borderWidth: 2, borderColor: 'orange' }, title: { fontSize: 18, fontWeight: 'bold', marginBottom: 5 } }); Slide 26 import React, { useRef } from 'react'; import { View, Text, FlatList, TouchableOpacity, StyleSheet, SafeAreaView } from 'react-native'; const DATA = Array.from({ length: 50 }, (_, i) => ({ id: i, title: `Елемент списку №${i}` })); export default function App() { const flatListRef = useRef(null); const goToTop = () => { flatListRef.current?.scrollToOffset({ offset: 0, animated: true, }); }; const goToEnd = () => { flatListRef.current?.scrollToEnd({ animated: true, }); }; return ( item.id.toString()} renderItem={({ item }) => ( {item.title} )} contentContainerStyle={{ paddingBottom: 100 }} /> На початок (Offset: 0) В кінець (End) ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#f5f5f5' }, item: { padding: 20, backgroundColor: 'white', borderBottomWidth: 1, borderBottomColor: '#eee', }, text: { fontSize: 16 }, floatingControls: { position: 'absolute', bottom: 30, left: 20, right: 20, flexDirection: 'row', justifyContent: 'space-between', }, btn: { flex: 1, padding: 15, borderRadius: 30, alignItems: 'center', marginHorizontal: 5, elevation: 5, shadowOpacity: 0.3, }, btnUp: { backgroundColor: '#4caf50' }, btnDown: { backgroundColor: '#2196f3' }, btnText: { color: 'white', fontWeight: 'bold' } }); Slide 27 import React, { useState, useCallback, useRef } from 'react'; import { View, Text, FlatList, StyleSheet, SafeAreaView } from 'react-native'; // Генеруємо 20 елементів const DATA = Array.from({ length: 20 }, (_, i) => ({ id: i, title: `Video #${i}` })); export default function App() { // Зберігаємо ID активного елемента const [activeItemId, setActiveItemId] = useState(null); // 1. НАЛАШТУВАННЯ ВИДИМОСТІ (Стабільна змінна) // itemVisiblePercentThreshold: 50 — елемент вважається "видимим", // якщо 50% його площі знаходиться у viewport. const viewabilityConfig = useRef({ itemVisiblePercentThreshold: 50, waitForInteraction: true, // (опційно) чекати скролу }).current; // 2. КОЛБЕК ЗМІНИ ВИДИМОСТІ (Обов'язково useCallback!) const onViewableItemsChanged = useCallback(({ viewableItems, changed }) => { // viewableItems — масив усіх елементів, які зараз видно // changed — масив елементів, статус видимості яких змінився if (viewableItems.length > 0) { // Беремо перший видимий елемент і робимо його активним const firstVisibleItem = viewableItems[0]; setActiveItemId(firstVisibleItem.item.id); console.log(`▶️ Play video: ${firstVisibleItem.item.title}`); } changed.forEach(item => { if (!item.isViewable) { console.log(`⏸️ Pause video: ${item.item.title}`); } }); }, []); // Рендер одного елемента const renderItem = ({ item }) => { const isPlaying = item.id === activeItemId; return ( {item.title} {isPlaying ? '▶️ PLAYING' : '⏸️ PAUSED'} ); }; return ( item.id.toString()} renderItem={renderItem} onViewableItemsChanged={onViewableItemsChanged} viewabilityConfig={viewabilityConfig} removeClippedSubviews={true} snapToInterval={300} // Висота елемента + відступи (щоб зупинялось рівно) decelerationRate="fast" /> ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#fff' }, item: { height: 280, margin: 10, justifyContent: 'center', alignItems: 'center', borderRadius: 15, }, title: { fontSize: 24, fontWeight: 'bold', color: '#fff', marginBottom: 10 }, status: { fontSize: 18, color: '#fff', fontWeight: '600' } }); Slide 32 import React, { useRef } from 'react'; import { View, Text, FlatList, TouchableOpacity, StyleSheet, SafeAreaView } from 'react-native'; const ITEM_HEIGHT = 100; const DATA = Array.from({ length: 5000 }, (_, i) => ({ id: i, title: `Елемент #${i}` })); export default function App() { const flatListRef = useRef(null); const jumpToBottom = () => { flatListRef.current?.scrollToIndex({ index: 4999, animated: true, viewPosition: 1 }); }; return ( Всього елементів: 5000 до #4999 item.id.toString()} getItemLayout={(data, index) => ({ length: ITEM_HEIGHT, // Висота одного елемента offset: ITEM_HEIGHT * index, // Відступ від верху (позиція Y) index, })} renderItem={({ item }) => ( {item.title} Фіксована висота: {ITEM_HEIGHT}px )} /> ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#f5f5f5' }, header: { padding: 15, backgroundColor: 'white', elevation: 4, zIndex: 1 }, headerText: { fontSize: 16, marginBottom: 10, textAlign: 'center' }, btn: { backgroundColor: '#6200ee', padding: 12, borderRadius: 8, alignItems: 'center' }, btnText: { color: 'white', fontWeight: 'bold' }, // Стилі елемента item: { height: ITEM_HEIGHT, // КРИТИЧНО ВАЖЛИВО: має збігатися з константою justifyContent: 'center', paddingHorizontal: 20, backgroundColor: 'white', borderBottomWidth: 1, borderBottomColor: '#eee', }, title: { fontSize: 20, fontWeight: 'bold' }, subtitle: { color: 'gray' } }); Slide 34 import React from 'react'; import { SectionList, Text, View, StyleSheet, SafeAreaView } from 'react-native'; const MENU_ITEMS = [ { title: '🍕 Піца', // Назва секції data: ['Маргарита', 'Пепероні'] }, { title: '🥗 Салати', data: ['Цезар', 'Грецький' ] }, { title: '🥤 Напої', data: ['Кола', 'Сік', 'Кава'] } ]; export default function App() { return ( item + index} renderItem={({ item }) => ( {item} )} stickySectionHeadersEnabled={true} /> ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#fff', paddingTop: 40 }, headerContainer: { backgroundColor: '#f2f2f2', padding: 10, borderBottomWidth: 1, borderBottomColor: '#ddd', }, headerText: { fontSize: 20, fontWeight: 'bold', color: '#333', }, itemContainer: { padding: 15, borderBottomWidth: 1, borderBottomColor: '#eee', }, itemText: { fontSize: 16, } }); Slide 35 import React from 'react'; import { SectionList, Text, View, StyleSheet, SafeAreaView } from 'react-native'; const MENU_ITEMS = [ { title: '🍕 Піца', // Назва секції data: ['Маргарита', 'Пепероні'] }, { title: '🥗 Салати', data: ['Цезар', 'Грецький' ] }, { title: '🥤 Напої', data: ['Кола', 'Сік', 'Кава'] } ]; export default function App() { return ( item + index} renderSectionHeader={({ section: { title } }) => ( {title} )} renderItem={({ item }) => ( {item} )} stickySectionHeadersEnabled={true} /> ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#fff', paddingTop: 40 }, headerContainer: { backgroundColor: '#f2f2f2', padding: 10, borderBottomWidth: 1, borderBottomColor: '#ddd', }, headerText: { fontSize: 20, fontWeight: 'bold', color: '#333', }, itemContainer: { padding: 15, borderBottomWidth: 1, borderBottomColor: '#eee', }, itemText: { fontSize: 16, } }); Slide 36 import React from 'react'; import { SectionList, Text, View, StyleSheet, SafeAreaView } from 'react-native'; const MENU_ITEMS = [ { title: '🍕 Піца', // Назва секції data: ['Маргарита', 'Пепероні'] }, { title: '🥗 Салати', data: ['Цезар', 'Грецький' ] }, { title: '🥤 Напої', data: ['Кола', 'Сік', 'Кава'] } ]; export default function App() { return ( item + index} renderSectionHeader={({ section: { title } }) => ( {title} )} renderItem={({ item }) => ( {item} )} renderSectionFooter={({ section }) => { return ( Кількість позицій: {section.data.length} ); }} stickySectionHeadersEnabled={true} /> ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#fff', paddingTop: 40 }, headerContainer: { backgroundColor: '#f2f2f2', padding: 10, borderBottomWidth: 1, borderBottomColor: '#ddd', }, headerText: { fontSize: 20, fontWeight: 'bold', color: '#333', }, itemContainer: { padding: 15, borderBottomWidth: 1, borderBottomColor: '#eee', }, itemText: { fontSize: 16, } }); Slide 37 import React from 'react'; import { SectionList, Text, View, StyleSheet, SafeAreaView, Button } from 'react-native'; const FINANCIAL_REPORTS = [ { title: 'Q4 2025 (Жовтень - Грудень)', data: ['Баланс (Form 1).pdf', 'Звіт про прибутки (Form 2).xlsx', 'Аудиторський висновок.docx'] }, { title: 'Q3 2025 (Липень - Вересень)', data: ['Баланс (Form 1).pdf', 'Звіт про рух коштів.xlsx'] }, { title: 'Q2 2025 (Квітень - Червень)', data: ['Коригування бюджету.pdf', 'Податкова декларація.xml'] } ]; export default function App() { const renderHeader = () => ( АРХІВ ДОКУМЕНТООБІГУ Статус сервера: ONLINE Останнє оновлення: 06.02.2026 14:30 Фільтр: Всі підрозділи ▼ ); const renderFooter = () => ( КОНФІДЕНЦІЙНО Інформація, що міститься в цьому списку, призначена виключно для внутрішнього користування співробітниками відділу фінансів. Розповсюдження заборонено згідно з політикою NDA. v.4.5.1 (Build 8902)