SectionList组件,是高性能的分组(section)列表组件,支持下面这些常用的功能:
- 完全跨平台。
- 行组件显示或隐藏时可配置回调事件。
- 支持单独的头部组件。
- 支持单独的尾部组件。
- 支持自定义行间分隔线。
- 支持分组的头部组件。
- 支持分组的分隔线。
- 支持多种数据源结构
- 支持下拉刷新。
- 支持上拉加载。
SectionList常用属性
属性 | 说明 | 备注 | |
---|---|---|---|
sections |
用来渲染的数据,类似于FlatList中的data 属性。 |
||
initialNumToRender |
指定一开始渲染的元素数量,最好刚刚够填满一个屏幕,这样保证了用最短的时间给用户呈现可见的内容。 | 第一批次渲染的元素不会在滑动过程中被卸载,这样是为了保证用户执行返回顶部的操作时,不需要重新渲染首批元素。 | |
keyExtractor |
用于为给定的item生成一个不重复的key 。 |
Key的作用是使React能够区分同类元素的不同个体,以便在刷新时能够确定其变化的位置,减少重新渲染的开销。若不指定此函数,则默认抽取item.key作为key值。若item.key也不存在,则使用数组下标。该函数只设置了每行(item)的key,对于每个组(section)仍然需要另外设置key。 | |
onRefresh |
设置了此选项,会在列表头部添加一个标准的RefreshControl 控件,以便实现“下拉刷新”的功能。 |
你需要正确设置refreshing 属性。 |
|
refreshing |
在等待加载新数据时将此属性设为true ,列表就会显示出一个正在加载的符号。 |
||
ListHeaderComponent |
头部组件。 | ||
ListFooterComponent |
尾部组件。 | ||
ListEmptyComponent |
当列表数据为空时渲染的组件。 | ||
renderItem |
用来渲染每一个section中的每一个列表项的默认渲染器。 | 可以在section级别上进行覆盖重写。必须返回一个react组件 | |
ItemSeparatorComponent |
行与行之间的分隔线组件。不会出现在第一行之前和最后一行之后。 | ||
renderSectionFooter |
每个组的尾部组件。 | ||
renderSectionHeader |
在每个section的头部渲染。 | ||
SectionSeparatorComponent |
在每个section的顶部和底部渲染(区别于ItemSeparatorComponent ,它仅在列表项之间渲染)。 |
它的作用是为了从视觉上把section与它上方或下方的headers区别开来,从这个意义上讲,它的作用和ItemSeparatorComponent是一样的 |
废话少说,直接上代码:
import React, {Component} from 'react';
import {
Platform,
StyleSheet,
Text,
View,
SectionList,
TouchableOpacity
} from 'react-native';
import {connect} from 'react-redux';
import Immutable from 'immutable';
// 初始化总数据
const initArr = Immutable.fromJS([
{date:'8月',income:'12345元',expenditure:'2520元',children:[
{date:'8月12日',time:'18:25',orderCode:'SO18081200005',transCode:'123456',weight:'69.5Kg',money:'+241.00元',type:'收入'},
{date:'8月10日',time:'12:01',orderCode:'SO18081000004',transCode:'123789',weight:'968.6Kg',money:'+8834.00元',type:'收入'},
{date:'8月2日',time:'10:08',orderCode:'SO18080200003',transCode:'309876',weight:'465.6Kg',money:'-2520.00元',type:'支出'},
{date:'8月1日',time:'09:30',orderCode:'SO18080100002',transCode:'783456',weight:'169.3Kg',money:'+1526.00元',type:'收入'},
{date:'8月1日',time:'06:47',orderCode:'SO18080100001',transCode:'456234',weight:'395.6Kg',money:'+3234.00元',type:'收入'}
]},
{date:'7月',income:'16365元',expenditure:'4525元',children:[
{date:'7月31日',time:'18:25',orderCode:'SO18071200005',transCode:'123456',weight:'69.5Kg',money:'+241.00元',type:'收入'},
{date:'7月20日',time:'12:01',orderCode:'SO18071200004',transCode:'123789',weight:'968.6Kg',money:'+8834.00元',type:'收入'},
{date:'7月16日',time:'10:08',orderCode:'SO18071200003',transCode:'309876',weight:'465.6Kg',money:'-2520.00元',type:'支出'},
{date:'7月12日',time:'09:30',orderCode:'SO18071200002',transCode:'783456',weight:'169.3Kg',money:'+7526.00元',type:'收入'},
{date:'7月5日',time:'06:47',orderCode:'SO18070500001',transCode:'456234',weight:'395.6Kg',money:'+3234.00元',type:'收入'},
{date:'7月3日',time:'10:08',orderCode:'SO18070300007',transCode:'309876',weight:'465.6Kg',money:'-2520.00元',type:'支出'}
]},
{date:'6月',income:'23940元',expenditure:'11560元',children:[
{date:'6月31日',time:'18:25',orderCode:'SO18061200005',transCode:'123456',weight:'69.5Kg',money:'+241.00元',type:'收入'},
{date:'6月20日',time:'12:01',orderCode:'SO18061200004',transCode:'123789',weight:'968.6Kg',money:'+8834.00元',type:'收入'},
{date:'6月16日',time:'10:08',orderCode:'SO18061200003',transCode:'309876',weight:'465.6Kg',money:'-2520.00元',type:'支出'},
{date:'6月12日',time:'09:30',orderCode:'SO18061200002',transCode:'783456',weight:'169.3Kg',money:'+7526.00元',type:'收入'},
{date:'6月5日',time:'06:47',orderCode:'SO18060500001',transCode:'456234',weight:'395.6Kg',money:'+3234.00元',type:'收入'},
{date:'6月3日',time:'10:08',orderCode:'SO18060300007',transCode:'309876',weight:'465.6Kg',money:'-520.00元',type:'支出'}
]},
{date:'5月',income:'12005元',expenditure:'8520元',children:[
{date:'5月31日',time:'18:25',orderCode:'SO18051200005',transCode:'123456',weight:'69.5Kg',money:'+241.00元',type:'收入'},
{date:'5月20日',time:'12:01',orderCode:'SO18051200004',transCode:'123789',weight:'968.6Kg',money:'+8834.00元',type:'收入'},
{date:'5月16日',time:'10:08',orderCode:'SO18051200003',transCode:'309876',weight:'465.6Kg',money:'-2520.00元',type:'支出'},
{date:'5月12日',time:'09:30',orderCode:'SO18051200002',transCode:'783456',weight:'169.3Kg',money:'+7526.00元',type:'收入'},
{date:'5月5日',time:'06:47',orderCode:'SO18050500001',transCode:'456234',weight:'395.6Kg',money:'+3234.00元',type:'收入'},
{date:'5月3日',time:'10:08',orderCode:'SO18050300007',transCode:'309876',weight:'465.6Kg',money:'-1520.00元',type:'支出'}
]},
{date:'4月',income:'72367元',expenditure:'7890元',children:[
{date:'4月31日',time:'18:25',orderCode:'SO18041200005',transCode:'123456',weight:'69.5Kg',money:'+241.00元',type:'收入'},
{date:'4月20日',time:'12:01',orderCode:'SO18041200004',transCode:'123789',weight:'968.6Kg',money:'+8834.00元',type:'收入'},
{date:'4月16日',time:'10:08',orderCode:'SO18041200003',transCode:'309876',weight:'465.6Kg',money:'-2520.00元',type:'支出'},
{date:'4月12日',time:'09:30',orderCode:'SO18041200002',transCode:'783456',weight:'169.3Kg',money:'+7526.00元',type:'收入'},
{date:'4月5日',time:'06:47',orderCode:'SO18040500001',transCode:'456234',weight:'395.6Kg',money:'+3234.00元',type:'收入'},
{date:'4月3日',time:'10:08',orderCode:'SO18040300007',transCode:'309876',weight:'465.6Kg',money:'-2520.00元',type:'支出'}
]},
{date:'3月',income:'12390元',expenditure:'78520元',children:[
{date:'3月31日',time:'18:25',orderCode:'SO18031200005',transCode:'123456',weight:'69.5Kg',money:'+241.00元',type:'收入'},
{date:'3月20日',time:'12:01',orderCode:'SO18031200004',transCode:'123789',weight:'968.6Kg',money:'+8834.00元',type:'收入'},
{date:'3月16日',time:'10:08',orderCode:'SO18031200003',transCode:'309876',weight:'465.6Kg',money:'-2520.00元',type:'支出'},
{date:'3月12日',time:'09:30',orderCode:'SO18031200002',transCode:'783456',weight:'169.3Kg',money:'+7526.00元',type:'收入'},
{date:'3月5日',time:'06:47',orderCode:'SO18030500001',transCode:'456234',weight:'395.6Kg',money:'+3234.00元',type:'收入'},
{date:'3月3日',time:'10:08',orderCode:'SO18030300007',transCode:'309876',weight:'465.6Kg',money:'-22520.00元',type:'支出'},
{date:'3月3日',time:'10:08',orderCode:'SO18030300007',transCode:'309876',weight:'465.6Kg',money:'-22520.00元',type:'支出'}
]},
{date:'2月',income:'56340元',expenditure:'9527元',children:[
{date:'2月31日',time:'18:25',orderCode:'SO18021200005',transCode:'123456',weight:'69.5Kg',money:'-241.00元',type:'支出'},
{date:'2月20日',time:'12:01',orderCode:'SO18021200004',transCode:'123789',weight:'968.6Kg',money:'+8834.00元',type:'收入'},
{date:'2月16日',time:'10:08',orderCode:'SO18021200003',transCode:'309876',weight:'465.6Kg',money:'-2520.00元',type:'支出'},
{date:'2月12日',time:'09:30',orderCode:'SO18021200002',transCode:'783456',weight:'169.3Kg',money:'+7526.00元',type:'收入'},
{date:'2月5日',time:'06:47',orderCode:'SO18020500001',transCode:'456234',weight:'395.6Kg',money:'+3234.00元',type:'收入'},
{date:'2月3日',time:'10:08',orderCode:'SO18020300007',transCode:'309876',weight:'465.6Kg',money:'-2520.00元',type:'支出'}
]},
]);
class SectionListDemo extends Component{
constructor(props) {
super(props);
this.state = {
//改变数据的数组
dataSource: initArr.toJS()
};
//for循环添加字段、删除字段
for (let i = 0; i < this.state.dataSource.length; i++) {
this.state.dataSource[i]['data'] = [];
this.state.dataSource[i]['key'] = I;
this.state.dataSource[i]['isShow'] = 'off';
delete this.state.dataSource[i]['children'];
}
this.renderItem = this.renderItem.bind(this);
this.renderSectionHeader = this.renderSectionHeader.bind(this);
}
//渲染每一个section中的每一个列表项
renderItem(data){
return(
<View style={{backgroundColor:'white', flexDirection:'row',justifyContent:'space-between',paddingLeft: 5,paddingVertical: 10}}>
<View>
<View style={{flexDirection:'row'}}>
<Text style={styles.textStyle}>{data.item.date}</Text>
<Text style={styles.textStyle}>{data.item.orderCode}</Text>
</View>
<View style={{flexDirection:'row'}}>
<Text style={styles.textStyle}>{data.item.time}</Text>
<Text style={[styles.textStyle,{fontWeight:'bold'}]}>{data.item.money}</Text>
<Text style={styles.textStyle}>{data.item.weight}</Text>
</View>
</View>
<Text style={{alignSelf:'center',fontSize:16,color: '#FA5741', marginRight:15}}>{data.item.type}</Text>
</View>
);
}
// 根据isShow状态判断,展开改变数据源,增加数组数据,合上删除数组里的数据
show(data){
if (data.isShow==='off') {
this.state.dataSource[data.key]['data'] = initArr.toJS()[data.key].children;
this.state.dataSource[data.key]['isShow'] = 'on';
this.setState({
dataSource:this.state.dataSource,
});
}else{
this.state.dataSource[data.key]['data'] = [];
this.state.dataSource[data.key]['isShow'] = 'off';
this.setState({
dataSource:this.state.dataSource,
});
}
}
//渲染每个section的头部
renderSectionHeader({section}){
return(
<TouchableOpacity
style={{
backgroundColor:'#f1f2f3',
justifyContent: 'center',
borderBottomWidth:1,
borderBottomColor:'#e8e8e8',
padding: 5
}}
onPress={()=>{this.show(section)}}>
<View>
<Text style={{fontSize:18,padding:5}}>{section.date}</Text>
<View style={{flexDirection:'row'}}>
<Text style={{fontSize:15,padding:5}}>收入:{section.income}</Text>
<Text style={{fontSize:15,marginLeft:25,padding:5}}>支出:{section.expenditure}</Text>
</View>
</View>
</TouchableOpacity>
);
}
renderItemSeparator() {
return (
<View style={styles.divideLine} ></View>
);
}
renderSectionSeparator() {
return (
<View style={{height:1,backgroundColor:'red'}} />
);
}
extraUniqueKey(item,index){
return index+item;
}
render() {
console.log('========'+JSON.stringify(this.state.dataSource));
return (
<View style={styles.container}>
<SectionList
sections={this.state.dataSource}// 数据源
renderItem={this.renderItem} // 渲染每一个section中的每一个列表项
keyExtractor = {this.extraUniqueKey}// 生成一个不重复的key
renderSectionHeader={this.renderSectionHeader}// 渲染每个section的头部
scrollEnabled={true}//默认是true,false禁止滚动
ItemSeparatorComponent={this. renderItemSeparator.bind(this)}// item分隔线组件
SectionSeparatorComponent={this.renderSectionSeparator.bind(this)} // section分隔线组件
>
</SectionList>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#FFF',
},
header:{
height: 64,
paddingTop: 14,
backgroundColor:'white',
flexDirection:'row',
},
textStyle:{
fontSize: 15,
marginLeft: 5,
padding: 5,
},
divideLine:{
height: 1,
backgroundColor: '#e8e8e8',
},
});
const mapStateToProps = state => ({
nav: state.nav,
})
const mapDispatchToProps = (dispatch) => {
return {
dispatch
}
}
export default connect(mapStateToProps, mapDispatchToProps)(SectionListDemo)
上效果图:
QQ20180726-164452.gif
网友评论