ReactNative 应用 FlatList 实现分组列表

举报
SHQ5785 发表于 2023/04/22 09:53:34 2023/04/22
【摘要】 一、功能简介FlatList为高性能的简单列表组件,支持下面这些常用的功能:完全跨平台。支持水平布局模式。行组件显示或隐藏时可配置回调事件。支持单独的头部组件。支持单独的尾部组件。支持自定义行间分隔线。支持下拉刷新。支持上拉加载。支持跳转到指定行(ScrollToIndex)。如果需要分组/类/区(section),请使用SectionList。FlatList和SectionList都是...

一、功能简介

FlatList为高性能的简单列表组件,支持下面这些常用的功能:

  • 完全跨平台。
  • 支持水平布局模式。
  • 行组件显示或隐藏时可配置回调事件。
  • 支持单独的头部组件。
  • 支持单独的尾部组件。
  • 支持自定义行间分隔线。
  • 支持下拉刷新。
  • 支持上拉加载。
  • 支持跳转到指定行(ScrollToIndex)。
  • 如果需要分组/类/区(section),请使用SectionList

FlatListSectionList都是以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,
  }

})

六、拓展阅读

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。