ReactNative进阶(四十一):应用FlatList实现分组列表
Posted No Silver Bullet
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ReactNative进阶(四十一):应用FlatList实现分组列表相关的知识,希望对你有一定的参考价值。
功能简介
FlatList
高性能的简单列表组件,支持下面这些常用的功能:
- 完全跨平台。
- 支持水平布局模式。
- 行组件显示或隐藏时可配置回调事件。
- 支持单独的头部组件。
- 支持单独的尾部组件。
- 支持自定义行间分隔线。
- 支持下拉刷新。
- 支持上拉加载。
- 支持跳转到指定行(ScrollToIndex)。
- 如果需要分组/类/区(section),请使用SectionList。
FlatList
和SectionList
都是以VirtualizedList为底层实现的,FlatList
具有更高的灵活性(比如说在使用 immutable
data 而不是 普通数组)的时候,才应该考虑使用VirtualizedList。
Vritualization
通过维护一个有限的渲染窗口(其中包含可见的元素),并将渲染窗口之外的元素全部用合适的定长空白空间代替的方式,极大的改善了内存消耗以及在大数据量情况下的使用性能。这个渲染窗口能响应滚动行为。当一个元素离可视区太远时,它就有一个较低优先级;否则就获得一个较高的优先级。渲染窗口通过这种方式逐步渲染其中的元素(在进行了任何交互之后),以尽量减少出现空白区域的可能性。
属性说明
属性名(类型) | 说明 |
---|---|
data | 列表数据 |
horizontal | 设置为true则变为水平列表,默认false。 |
ItemSeparatorComponent | 分割线组件,不会出现在第一行之前和最后一行之后。 |
ListFooterComponent | 结尾组件 |
ListHeaderComponent | 头组件 |
ListEmptyComponent | 列表为空时渲染该组件。可以是React Component, 也可以是一个render函数, 或者渲染好的element。 |
extraData | 如果有除data以外的数据用在列表中(不论是用在renderItem 还是Header 或者Footer 中),请在此属性中指定。同时此数据在修改时也需要先修改其引用地址(比如先复制到一个新的Object或者数组中),然后再修改其值,否则界面很可能不会刷新。 |
getItem | 获取每个Item |
getItemCount | 获取Item数量 |
initialNumToRender | 指定一开始渲染的元素数量,最好刚刚够填满一个屏幕,这样保证了用最短的时间给用户呈现可见的内容。注意这第一批次渲染的元素不会在滑动过程中被卸载,这样是为了保证用户执行返回顶部的操作时,不需要重新渲染首批元素。 |
initialScrollIndex | 指定渲染开始的item index |
keyExtractor | 此函数用于为给定的item生成一个不重复的key。Key的作用是使React能够区分同类元素的不同个体,以便在刷新时能够确定其变化的位置,减少重新渲染的开销。若不指定此函数,则默认抽取item.key作为key值。若item.key也不存在,则使用数组下标。 |
legacyImplementation | 设置为true则使用旧的ListView的实现。 |
numColumns | 多列布局只能在非水平模式下使用,即必须是horizontal={false} 。此时组件内元素会按照从左到右从上到下Z字形排列,类似启用了flexWrap 的布局。组件内元素必须是等高的——暂时还无法支持瀑布流布局。 |
columnWrapperStyle | numColumns 大于1时,设置每行的样式 |
onEndReached | 当列表被滚动到距离内容最底部不足onEndReachedThreshold 的距离时调用。 |
onEndReachedThreshold | 决定当距离内容最底部还有多远时触发onEndReached 回调。注意此参数是一个比值而非像素单位。比如,0.5表示距离内容最底部的距离为当前列表可见长度的一半时触发。 |
onRefresh | 如果设置了此选项,则会在列表头部添加一个标准的RefreshControl 控件,以便实现“下拉刷新”的功能。同时你需要正确设置refreshing 属性。 |
onViewableItemsChanged 【参数:info: {viewableItems: Array, changed: Array } viewableItems:当前可见的Item,changed:渲染或者隐藏的Item。 】 | 在可见行元素变化时调用。可见范围和变化频率等参数的配置请设置viewabilityconfig 属性. |
refreshing | 在等待加载新数据时将此属性设为true,列表就会显示出一个正在加载的符号。 |
renderItem | 根据行数据data,渲染每一行的组件。 |
getItemLayout | 如果知道行高可以用此方法节省动态计算行高的开销。 |
androidprogressViewOffset | 当需要在指定的偏移内显示加载指示器的时候,就可以设置这个值。 |
方法集合
方法名 | 说明 |
---|---|
scrollToEnd | 滚动到底部。如果不设置getItemLayout 属性的话,可能会比较卡。 |
scrollToIndex | 滚动到指定index的item。如果不设置getItemLayout 属性的话,无法跳转到当前可视区域以外的位置。 |
scrollToItem | 滚动到指定item,如果不设置getItemLayout 属性的话,可能会比较卡。 |
scrollToOffset | 滚动指定距离 |
简单应用示例
<FlatList
data={Details}
keyExtractor={(item, index) => index}
renderItem={this._renderItem(data)}
ListEmptyComponent={()=>{return(<Text style={styles.LookMoreStyle}>暂无记录</Text>)}}
// getItemLayout={(data,index)=>(
// {length: AdaptationModel.scaleHeight(46), offset:AdaptationModel.scaleHeight(46) * index, index}
// )}
/>
_renderItem(data){
return <View style={styles.item}>
<Text style={styles.text}>{data.item}</Text>
</View>
}
const styles = StyleSheet.create({
LookMoreStyle: {
height: 32,
width: AppSetting.ScreenWidth,
textAlign: 'center',
fontSize: AdaptationModel.setSpText(12),
paddingTop: 10,
backgroundColor: AppSetting.GRAY
},
item:{
backgroundColor: '#168',
height:200,
marginRight:15,
marginLeft:15,
marginBottom:15,
alignItems:'center',
//justifyContetnt:'center',
},
})
高阶应用示例
const {width,height}=Dimensions.get('window')
export default class Main extends Component{
// 构造
constructor(props) {
super(props);
}
refreshing(){
let timer = setTimeout(()=>{
clearTimeout(timer)
alert('刷新成功')
},1500)
}
_onload(){
let timer = setTimeout(()=>{
clearTimeout(timer)
alert('加载成功')
},1500)
}
render() {
var data = [];
for (var i = 0; i < 100; i++) {
data.push({key: i, title: i + ''});
}
return (
<View style={{flex:1}}>
<Button title='滚动到指定位置' onPress={()=>{
this._flatList.scrollToOffset({animated: true, offset: 2000});
}}/>
<View style={{flex:1}}>
<FlatList
ref={(flatList)=>this._flatList = flatList}
ListHeaderComponent={this._header}
ListFooterComponent={this._footer}
ItemSeparatorComponent={this._separator}
renderItem={this._renderItem}
onRefresh={this.refreshing}
refreshing={false}
onEndReachedThreshold={0}
onEndReached={
this._onload
}
numColumns ={3}
columnWrapperStyle={{borderWidth:2,borderColor:'black',paddingLeft:20}}
//horizontal={true}
getItemLayout={(data,index)=>(
{length: 100, offset: (100+2) * index, index}
)}
data={data}>
</FlatList>
</View>
</View>
);
}
_renderItem = (item) => {
var txt = '第' + item.index + '个' + ' title=' + item.item.title;
var bgColor = item.index % 2 == 0 ? 'red' : 'blue';
return <Text style={[{flex:1,height:100,backgroundColor:bgColor},styles.txt]}>{txt}</Text>
}
_header = () => {
return <Text style={[styles.txt,{backgroundColor:'black'}]}>这是头部</Text>;
}
_footer = () => {
return <Text style={[styles.txt,{backgroundColor:'black'}]}>这是尾部</Text>;
}
_separator = () => {
return <View style={{height:2,backgroundColor:'yellow'}}/>;
}
}
const styles=StyleSheet.create({
container:{
},
content:{
width:width,
height:height,
backgroundColor:'yellow',
justifyContent:'center',
alignItems:'center'
},
cell:{
height:100,
backgroundColor:'purple',
alignItems:'center',
justifyContent:'center',
borderBottomColor:'#ececec',
borderBottomWidth:1
},
txt: {
textAlign: 'center',
textAlignVertical: 'center',
color: 'white',
fontSize: 30,
}
})
拓展阅读
以上是关于ReactNative进阶(四十一):应用FlatList实现分组列表的主要内容,如果未能解决你的问题,请参考以下文章
ReactNative进阶(四十四):Mobile App适配性优化
ReactNative进阶(四十八):Mobile App适配性优化实战
跨平台应用开发进阶(四十一)使用Xcode打包 iOS 应用 archive 时四种证书的区别详解