一、简介
SectionList,分组列表,ReactNative中继提供的ListView和FlatList列表组件后的又一个很重要的分组列表组件。它的用法其实跟前面的FlatList差不多,但是SectionList组件性能更高,同时SectionList组件要比ListView组件使用简单的多。SectionList组件的功能非常强大,如下所示。现在我们来仔细研究一下这个组件的API。
- 完全跨平台。
- 可配置的可见性回调。
- 列表标题支持。
- 列出页脚支持。
- 项目分隔符支持。
- 节标题支持。
- 部分分隔符支持。
- 异构数据和项目渲染支持。
- 拉动以刷新。
- 滚动加载。
二、API
SectionList组件同样地对属性是必须直接提供的,有些是可选的。如下所示:
//分组基类SectionBase对象结构, 泛型为SectionItemT
type SectionBase<SectionItemT> = {
//数据源数组,必需属性
data: Array<SectionItemT>,
//每一组数据源的标识符 ,必需属性
key: string,
//每一组的每一个item组件,可选属性
renderItem?: ?(info: {item: SectionItemT, index: number}) => ?React.Element<any>,
//分割线,可选属性
ItemSeparatorComponent?: ?ReactClass<any>,
//标识符,可选属性
keyExtractor?: (item: SectionItemT) => string,
};
//必要的属性
//sections,是一个泛型数组,类型为SectionT,存储的是SectionBase对象
type RequiredProps<SectionT: SectionBase<any>> = {
sections: Array<SectionT>,
};
//可选的属性
type OptionalProps<SectionT: SectionBase<any>> = {
//每个部分中每个项目的默认渲染器。 可以逐段覆盖。
renderItem: (info: {item: Item, index: number}) => ?React.Element<any>,
//在每个部分的相邻项目之间渲染。每一个item的分割线
ItemSeparatorComponent?: ?ReactClass<any>,
//在列表的最开始呈现。表头
ListHeaderComponent?: ?ReactClass<any>,
//呈现在列表的最后。表尾
ListFooterComponent?: ?ReactClass<any>,
//在每个部分之间渲染。组分割线
SectionSeparatorComponent?: ?ReactClass<any>,
//一个标记属性,用于告诉列表重新渲染(因为它实现了`PureComponent`)。 //如果您的`renderItem`,Header,Footer等函数中的任何一个都依赖于`data`道具之外的任何东西,请将其粘贴在这里并一视同仁。
extraData?: any,
//页面初次渲染的个数,可以不用等所有页面渲染出来再显示UI
initialNumToRender: number,
//用于提取指定索引处给定项目的唯一键。 键用于缓存,并用作反应键以跟踪项的重新排序。 默认的提取器检查item.key,然后像react一样退回到使用索引。
keyExtractor: (item: Item, index: number) => string,
//滚动位置在渲染内容的onEndReachedThreshold范围内时调用一次。
onEndReached?: ?(info: {distanceFromEnd: number}) => void,
//列表的底边必须从内容的末尾到末尾(以列表的可见长度为单位)多远,才能触发onEndReached回调。 //因此,当内容的结尾在列表的可见长度的一半以内时,值为0.5将触发“ onEndReached”。
onEndReachedThreshold?: ?number,
//如果提供,将为“拉动刷新”功能添加标准的RefreshControl。
onRefresh?: ?() => void,
//当行的可视性发生变化时调用,如`viewabilityConfig`属性所定义。
onViewableItemsChanged?: ?(info: {
viewableItems: Array<ViewToken>,
changed: Array<ViewToken>,
}) => void,
//等待刷新之前的新数据时,将其设置为true。
refreshing?: ?boolean,
//呈现在每个部分的顶部。 尚不支持粘性标头。组头
renderSectionHeader?: ?(info: {section: SectionT}) => ?React.Element<any>,
//使节标题停留在屏幕顶部,直到下一个将其关闭。 仅在iOS上默认启用,因为这是该平台的平台标准。
stickySectionHeadersEnabled?: boolean,
};
三、使用
看完API,可以发现接收的数据数组sections存储的都是SectionBase,而每一个SectionBase内部都必需包含data数组和key唯一标识,剩余的元素是可选的。其实挺简单的,现在来实现一下部分功能,示例如下:
MySectionListView.js
import React, { Component } from 'react';
import {
StyleSheet,
View,
Image,
Text,
Dimensions,
SectionList
} from 'react-native';
const {width} = Dimensions.get('window');
const itemPadding = 20;
const itemWidth = (width-4*itemPadding)/3;
console.log('width:'+width);
const fetch_data = [
{
"type":"A",
"flowers":[
{
icon:require('../image/flower1.png'),
title:'玫瑰'
},
{
icon:require('../image/flower1.png'),
title:'玫瑰'
},
{
icon:require('../image/flower1.png'),
title:'玫瑰'
}
]
},
{
"type":"B",
"flowers":[
{
icon:require('../image/flower2.png'),
title:'草芽'
},
{
icon:require('../image/flower2.png'),
title:'草芽'
},
{
icon:require('../image/flower2.png'),
title:'草芽'
}
]
},
{
"type":"C",
"flowers":[
{
icon:require('../image/flower3.png'),
title:'向日葵'
},
{
icon:require('../image/flower3.png'),
title:'向日葵'
},
{
icon:require('../image/flower3.png'),
title:'向日葵'
}
]
},
{
"type":"D",
"flowers":[
{
icon:require('../image/flower4.png'),
title:'月季'
},
{
icon:require('../image/flower4.png'),
title:'月季'
},
{
icon:require('../image/flower4.png'),
title:'月季'
}
]
}
];
export default class MySectionListView extends Component{
//渲染item info: {item: Item, index: number}
_renderItem(info){
return (
<View style={styles.item}>
<Image style={styles.image} source={info.item.icon}/>
<Text style={styles.text}>{info.item.title}</Text>
</View>
)
}
//渲染组头 info: {section: SectionT}
_renderSectionHeader(info){
return (
<View style={styles.sectionHeader}>
<Text key={info.section.key}
style={{color:'white',fontSize: 25,justifyContent: 'center'}}>
{info.section.type}
</Text>
</View>
)
}
//渲染表头
_listHeaderComponent(){
return (
<View style={{width:width,height:200,backgroundColor:'red'}}/>
)
}
//渲染表尾
_listFooterComponent(){
return (
<View style={{width:width,height:200,backgroundColor:'green'}}/>
)
}
render() {
//sections数据源
let sections = [];
for (let i = 0; i < fetch_data.length; i++) {
//创建SectionBase对象,初始化key唯一标识,和data数组
let data = [];
const type = fetch_data[i].type;
const flowers = fetch_data[i].flowers;
for(let j=0; j<flowers.length; j++){
data.push(flowers[j]);
}
sections.push({key: i, data: data, type:type});
}
return (
<View style={styles.flex}>
<SectionList
sections={sections}
renderItem={this._renderItem}
keyExtractor={(item, index) => ("index:" + index + item)}
contentContainerStyle={styles.section}
renderSectionHeader={this._renderSectionHeader}
ListHeaderComponent={this._listHeaderComponent}
ListFooterComponent={this._listFooterComponent}
/>
</View>
);
}
}
const styles = StyleSheet.create({
flex: {
flex: 1,
},
center: {
alignItems: 'center',
justifyContent: 'center'
},
section: {
flexDirection: 'row',
flexWrap: 'wrap',
backgroundColor:'#EEE'
},
item: {
width: itemWidth,
marginTop: 10,
marginBottom: 10,
marginLeft: itemPadding,
justifyContent: 'center',
backgroundColor: '#21c6cd'
},
image: {
width: itemWidth,
height: 150
},
text: {
marginTop: 5,
width: itemWidth,
fontSize: 25,
textAlign: 'center'
},
sectionHeader: {
height: 30,
width: width,
backgroundColor: 'gray'
}
});
来源:https://www.cnblogs.com/XYQ-208910/p/12163156.html