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)
);
return (
item + index}
ListHeaderComponent={renderHeader}
ListFooterComponent={renderFooter}
renderSectionHeader={({ section: { title } }) => (
{title}
)}
renderItem={({ item }) => (
📄 {item}
245 KB
)}
/>
);
}
const styles = StyleSheet.create({
container: { flex: 1, backgroundColor: '#e0e0e0' },
listHeader: {
backgroundColor: '#37474f',
padding: 15,
borderBottomWidth: 4,
borderBottomColor: '#263238',
},
appTitle: { color: 'white', fontSize: 18, fontWeight: 'bold', marginBottom: 10 },
infoPanel: { flexDirection: 'row', justifyContent: 'space-between', marginBottom: 10 },
infoText: { color: '#b0bec5', fontSize: 10 },
filterBox: { backgroundColor: '#eceff1', padding: 8, borderRadius: 2 },
// СЕКЦІЇ
sectionHeader: {
backgroundColor: '#cfd8dc',
paddingVertical: 8,
paddingHorizontal: 15,
borderTopWidth: 1,
borderTopColor: '#90a4ae',
},
sectionTitle: { color: '#455a64', fontWeight: 'bold', fontSize: 12, textTransform: 'uppercase' },
// РЯДКИ
row: {
backgroundColor: 'white',
padding: 12,
borderBottomWidth: 1,
borderBottomColor: '#eceff1',
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center'
},
docName: { fontSize: 14, color: '#263238' },
docSize: { fontSize: 12, color: '#78909c' },
// ФУТЕР
listFooter: {
padding: 20,
backgroundColor: '#e0e0e0',
borderTopWidth: 1,
borderTopColor: '#b0bec5',
},
disclaimerHeader: { fontSize: 12, fontWeight: 'bold', color: '#d32f2f', marginBottom: 5 },
disclaimerText: { fontSize: 10, color: '#607d8b', textAlign: 'justify', lineHeight: 14 },
version: { marginTop: 15, textAlign: 'center', fontSize: 10, color: '#90a4ae' }
});
Slide 38
import React from 'react';
import { SectionList, Text, View, StyleSheet, SafeAreaView } from 'react-native';
const SETTINGS = [
{
title: 'Мережа',
data: ['Wi-Fi', 'Bluetooth', 'Мобільний звʼязок']
},
{
title: 'Екран',
data: ['Яскравість', 'Тайм-аут екрана']
},
{
title: 'Звук',
data: ['Гучність']
}
];
export default function App() {
return (
item + index}
renderSectionHeader={({ section: { title } }) => (
{title}
)}
renderItem={({ item }) => (
{item}
)}
ItemSeparatorComponent={() => (
)}
SectionSeparatorComponent={() => (
)}
/>
);
}
const styles = StyleSheet.create({
container: { flex: 1, backgroundColor: 'white', paddingTop: 40 },
header: {
backgroundColor: '#eee',
padding: 10,
borderLeftWidth: 5,
borderLeftColor: 'black'
},
headerText: { fontWeight: 'bold', fontSize: 18 },
item: {
padding: 15,
backgroundColor: 'white'
}
});
Slide 42
import React, { useRef } from 'react';
import { SectionList, Text, View, Button, SafeAreaView } from 'react-native';
const DATA = [
{ title: 'Група 1', data: ['А', 'Б', 'В', 'Г', 'Д'] },
{ title: 'Група 2', data: ['Е', 'Є', 'Ж', 'З', 'И'] },
{ title: 'Група 3', data: ['І', 'Ї', 'Й', 'К', 'Л'] },
];
export default function App() {
const listRef = useRef(null);
const go = () => {
listRef.current.scrollToLocation({
sectionIndex: 1, // Це "Група 2" (бо відлік з 0)
itemIndex: 3, // Це літера "З" (0=Е, 1=Є, 2=Ж, 3=З)
});
};
return (
item + index}
renderSectionHeader={({ section: { title } }) => (
{title}
)}
renderItem={({ item }) => (
{item}
)}
/>
);
}
Slide 58
import React from 'react';
import { FlatList, Text, View, StyleSheet, SafeAreaView } from 'react-native';
// Генеруємо 200 елементів
const DATA = Array.from({ length: 200 }, (_, i) => ({
id: i.toString(),
text: `Item #${i}`
}));
export default function DebugVirtualization() {
return (
Режим Debug: ON 🛠
item.id}
// Вмикає технічний оверлей React Native.
debug={true}
// Зменшуємо вікно рендеру до мінімуму (зазвичай 21).
// Це змусить список агресивно видаляти старі елементи.
windowSize={1}
initialNumToRender={1}
renderItem={({ item }) => (
{item.text}
Lorem ipsum
)}
/>
);
}
const styles = StyleSheet.create({
container: { flex: 1, backgroundColor: '#fff', paddingTop: 40 },
header: { fontSize: 20, fontWeight: 'bold', textAlign: 'center', color: '#d32f2f' },
subHeader: { textAlign: 'center', marginBottom: 10, color: '#555', paddingHorizontal: 20 },
item: {
height: 100, // Фіксована висота для наочності
justifyContent: 'center',
alignItems: 'center',
borderBottomWidth: 1,
borderColor: '#fff',
},
text: { fontSize: 24, fontWeight: 'bold' },
subText: { color: '#555' }
});