1. FlatList 基礎使用
import React from 'react';
import { View, Text, FlatList, StyleSheet } from 'react-native';
export const SimpleListDemo: React.FC = () => {
// 1. 準備數據
const data = [
{ id: '1', title: '項目 1' },
{ id: '2', title: '項目 2' },
{ id: '3', title: '項目 3' },
];
// 2. 定義如何渲染每一項
const renderItem = ({ item }) => (
<View style={styles.item}>
<Text>{item.title}</Text>
</View>
);
// 3. 渲染 FlatList
return (
<FlatList
data={data} // 數據源
renderItem={renderItem} // 渲染項
keyExtractor={item => item.id} // 指定 key
/>
);
};
const styles = StyleSheet.create({
item: {
padding: 20,
borderBottomWidth: 1,
borderBottomColor: '#ccc',
},
});
2. 添加頭部和底部
import React from 'react';
import { View, Text, FlatList, StyleSheet } from 'react-native';
export const ListWithHeaderFooter: React.FC = () => {
const data = [/* ... */];
// 1. 定義頭部組件
const ListHeader = () => (
<View style={styles.header}>
<Text>這是列表頭部</Text>
</View>
);
// 2. 定義底部組件
const ListFooter = () => (
<View style={styles.footer}>
<Text>這是列表底部</Text>
</View>
);
return (
<FlatList
data={data}
renderItem={({ item }) => (
<View style={styles.item}>
<Text>{item.title}</Text>
</View>
)}
ListHeaderComponent={ListHeader} // 添加頭部
ListFooterComponent={ListFooter} // 添加底部
keyExtractor={item => item.id}
/>
);
};
const styles = StyleSheet.create({
header: {
padding: 15,
backgroundColor: '#f0f0f0',
},
item: {
padding: 20,
borderBottomWidth: 1,
borderBottomColor: '#ccc',
},
footer: {
padding: 15,
backgroundColor: '#f0f0f0',
},
});
3. 下拉刷新和上拉加載
import React, { useState } from 'react';
import {
View,
Text,
FlatList,
RefreshControl,
ActivityIndicator,
StyleSheet
} from 'react-native';
export const RefreshLoadMoreList: React.FC = () => {
const [refreshing, setRefreshing] = useState(false);
const [loading, setLoading] = useState(false);
const [data, setData] = useState([/* 初始數據 */]);
// 1. 處理下拉刷新
const onRefresh = async () => {
setRefreshing(true);
try {
// 這裡請求新數據
const newData = await fetchNewData();
setData(newData);
} finally {
setRefreshing(false);
}
};
// 2. 處理上拉加載更多
const onLoadMore = async () => {
if (loading) return;
setLoading(true);
try {
// 這裡請求更多數據
const moreData = await fetchMoreData();
setData([...data, ...moreData]);
} finally {
setLoading(false);
}
};
return (
<FlatList
data={data}
renderItem={({ item }) => (
<View style={styles.item}>
<Text>{item.title}</Text>
</View>
)}
// 下拉刷新配置
refreshControl={
<RefreshControl
refreshing={refreshing}
onRefresh={onRefresh}
/>
}
// 上拉加載配置
onEndReached={onLoadMore}
onEndReachedThreshold={0.1}
ListFooterComponent={
loading ? <ActivityIndicator /> : null
}
/>
);
};
4. 常用配置項說明
<FlatList
// 基礎配置
data={data} // 列表數據
renderItem={renderItem} // 渲染每一項的方法
keyExtractor={item => item.id} // 生成 key 的方法
// 樣式相關
contentContainerStyle={styles.list} // 內容容器樣式
style={styles.container} // FlatList 本身樣式
// 性能優化
initialNumToRender={10} // 首次渲染的項目數
maxToRenderPerBatch={10} // 每次渲染的最大數量
windowSize={5} // 渲染窗口大小
// 滾動相關
showsVerticalScrollIndicator={false} // 是否顯示滾動條
scrollEnabled={true} // 是否可以滾動
/>
5. 空列表處理
import React from 'react';
import { View, Text, FlatList, StyleSheet } from 'react-native';
export const EmptyList: React.FC = () => {
const data = []; // 空數據
const EmptyComponent = () => (
<View style={styles.empty}>
<Text>暫無數據</Text>
</View>
);
return (
<FlatList
data={data}
renderItem={({ item }) => (/* ... */)}
ListEmptyComponent={EmptyComponent} // 當數據為空時顯示
/>
);
};
const styles = StyleSheet.create({
empty: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
padding: 20,
},
});
2. SessionList基礎使用
import React from 'react';
import { View, Text, SectionList, StyleSheet } from 'react-native';
export const SimpleSectionList: React.FC = () => {
// 1. 準備分組數據
const sections = [
{
title: '分組A',
data: [
{ id: '1', name: '項目A1' },
{ id: '2', name: '項目A2' },
]
},
{
title: '分組B',
data: [
{ id: '3', name: '項目B1' },
{ id: '4', name: '項目B2' },
]
}
];
// 2. 渲染每個項目
const renderItem = ({ item }) => (
<View style={styles.item}>
<Text>{item.name}</Text>
</View>
);
// 3. 渲染分組標題
const renderSectionHeader = ({ section }) => (
<View style={styles.header}>
<Text style={styles.headerText}>{section.title}</Text>
</View>
);
return (
<SectionList
sections={sections} // 分組數據
renderItem={renderItem} // 渲染每個項目
renderSectionHeader={renderSectionHeader} // 渲染分組標題
keyExtractor={item => item.id} // key提取器
/>
);
}
const styles = StyleSheet.create({
item: {
padding: 15,
backgroundColor: 'white',
},
header: {
padding: 10,
backgroundColor: '#f0f0f0',
},
headerText: {
fontSize: 16,
fontWeight: 'bold',
},
});
2. 添加分組間距和分隔線
import React from 'react';
import { View, SectionList, StyleSheet } from 'react-native';
export const SectionListWithSeparators: React.FC = () => {
const sections = [/* ... */];
// 1. 項目之間的分隔線
const ItemSeparator = () => (
<View style={styles.itemSeparator} />
);
// 2. 分組之間的間距
const SectionSeparator = () => (
<View style={styles.sectionSeparator} />
);
return (
<SectionList
sections={sections}
renderItem={renderItem}
renderSectionHeader={renderSectionHeader}
ItemSeparatorComponent={ItemSeparator} // 項目分隔線
SectionSeparatorComponent={SectionSeparator} // 分組分隔線
stickySectionHeadersEnabled={true} // 分組標題固定
/>
);
};
const styles = StyleSheet.create({
itemSeparator: {
height: 1,
backgroundColor: '#eee',
},
sectionSeparator: {
height: 10,
backgroundColor: '#f5f5f5',
},
});
3. 下拉刷新和加載更多
import React, { useState } from 'react';
import {
SectionList,
RefreshControl,
ActivityIndicator
} from 'react-native';
export const RefreshableSectionList: React.FC = () => {
const [refreshing, setRefreshing] = useState(false);
const [loading, setLoading] = useState(false);
const [sections, setSections] = useState([/* 初始數據 */]);
// 1. 處理下拉刷新
const onRefresh = async () => {
setRefreshing(true);
try {
const newData = await fetchNewData();
setSections(newData);
} finally {
setRefreshing(false);
}
};
// 2. 處理加載更多
const onLoadMore = async () => {
if (loading) return;
setLoading(true);
try {
const moreData = await fetchMoreData();
setSections([...sections, ...moreData]);
} finally {
setLoading(false);
}
};
return (
<SectionList
sections={sections}
renderItem={renderItem}
renderSectionHeader={renderSectionHeader}
// 下拉刷新
refreshControl={
<RefreshControl
refreshing={refreshing}
onRefresh={onRefresh}
/>
}
// 加載更多
onEndReached={onLoadMore}
onEndReachedThreshold={0.2}
ListFooterComponent={
loading ? <ActivityIndicator /> : null
}
/>
);
};
4.空列表和列表頭尾
import React from 'react';
import { View, Text, SectionList } from 'react-native';
export const SectionListWithHeaderFooter: React.FC = () => {
const sections = [/* ... */];
// 1. 列表頭部
const ListHeader = () => (
<View style={styles.listHeader}>
<Text>列表頭部</Text>
</View>
);
// 2. 列表底部
const ListFooter = () => (
<View style={styles.listFooter}>
<Text>列表底部</Text>
</View>
);
// 3. 空列表顯示
const ListEmpty = () => (
<View style={styles.empty}>
<Text>暫無數據</Text>
</View>
);
return (
<SectionList
sections={sections}
renderItem={renderItem}
renderSectionHeader={renderSectionHeader}
ListHeaderComponent={ListHeader}
ListFooterComponent={ListFooter}
ListEmptyComponent={ListEmpty}
/>
);
};
5. 常用配置項總結
<SectionList
// 基礎配置
sections={sections} // 分組數據
renderItem={renderItem} // 渲染項目
renderSectionHeader={renderSectionHeader} // 渲染分組標題
keyExtractor={(item) => item.id} // key提取器
// 分組相關
stickySectionHeadersEnabled={true} // 分組標題是否固定
renderSectionFooter={renderSectionFooter} // 渲染分組底部
// 分隔線
ItemSeparatorComponent={ItemSeparator} // 項目分隔線
SectionSeparatorComponent={SectionSeparator} // 分組分隔線
// 性能優化
initialNumToRender={10} // 初始渲染數量
maxToRenderPerBatch={10} // 每批渲染數量
windowSize={5} // 渲染窗口大小
// 樣式相關
contentContainerStyle={styles.container} // 內容容器樣式
style={styles.list} // 列表樣式
/>