ReactNative之FlatList的具体使用方法

时间:2021-05-26

之前使用的组件是ListView,当时要添加一个下拉刷新,上拉加载的功能,所以对ListView做了一些封装,但是后来看官方文档,不建议再使用ListView,因为效率问题,做过Android的朋友都知道,Android的ListView如果不自己处理一下,也是有效率问题的。所以官方又推出了FlatList,而且自带上拉下拉的功能。

功能简介

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

    使用

    FlatList如果只做简单使用也是很简单的,这里我们会分难以程度,逐渐介绍:

    直接使用

    <FlatListdata={[{key: 'a'}, {key: 'b'}]}renderItem={({item}) => <Text>{item.key}</Text>}/>

    可以看出跟之前的ListView很像,但是其中少了dataSource,这里,我们只需要传递数据,其它的都交给FlatList处理好了。

    属性说明

  • ItemSeparatorComponent行与行之间的分隔线组件。不会出现在第一行之前和最后一行之后。在这里可以根据需要插入一个view
  • ListEmptyComponent列表为空时渲染该组件。可以是React Component, 也可以是一个render函数, 或者渲染好的element。
  • ListFooterComponent尾部组件
  • ListHeaderComponent头部组件
  • columnWrapperStyle如果设置了多列布局(即将numColumns值设为大于1的整数),则可以额外指定此样式作用在每行容器上。
  • data为了简化起见,data属性目前只支持普通数组。如果需要使用其他特殊数据结构,例如immutable数组,请直接使用更底层的VirtualizedList组件。
  • extraData如果有除data以外的数据用在列表中(不论是用在renderItem还是Header或者Footer中),请在此属性中指定。同时此数据在修改时也需要先修改其引用地址(比如先复制到一个新的Object或者数组中),然后再修改其值,否则界面很可能不会刷新。
  • getItem获取每个Item
  • getItemCount获取Item属相
  • getItemLayout是一个可选的优化,用于避免动态测量内容尺寸的开销,不过前提是你可以提前知道内容的高度。如果你的行高是固定的getItemLayout用起来就既高效又简单,类似下面这样:getItemLayout={(data, index) => ( {length: 行高, offset: 行高 * index, index} )}注意如果你指定了SeparatorComponent,请把分隔线的尺寸也考虑到offset的计算之中。
  • horizontal设置为true则变为水平布局模式。
  • initialNumToRender指定一开始渲染的元素数量,最好刚刚够填满一个屏幕,这样保证了用最短的时间给用户呈现可见的内容。注意这第一批次渲染的元素不会在滑动过程中被卸载,这样是为了保证用户执行返回顶部的操作时,不需要重新渲染首批元素。
  • initialScrollIndex指定渲染开始的item index
  • keyExtractor此函数用于为给定的item生成一个不重复的key。Key的作用是使React能够区分同类元素的不同个体,以便在刷新时能够确定其变化的位置,减少重新渲染的开销。若不指定此函数,则默认抽取item.key作为key值。若item.key也不存在,则使用数组下标。
  • legacyImplementation设置为true则使用旧的ListView的实现。
  • numColumns多列布局只能在非水平模式下使用,即必须是horizontal={false}。此时组件内元素会从左到右从上到下按Z字形排列,类似启用了flexWrap的布局。组件内元素必须是等高的——暂时还无法支持瀑布流布局。
  • onEndReached当列表被滚动到距离内容最底部不足onEndReachedThreshold的距离时调用。
  • onEndReachedThreshold决定当距离内容最底部还有多远时触发onEndReached回调。注意此参数是一个比值而非像素单位。比如,0.5表示距离内容最底部的距离为当前列表可见长度的一半时触发。
  • onRefresh如果设置了此选项,则会在列表头部添加一个标准的RefreshControl控件,以便实现“下拉刷新”的功能。同时你需要正确设置refreshing属性。
  • onViewableItemsChanged在可见行元素变化时调用。可见范围和变化频率等参数的配置请设置viewabilityconfig属性
  • refreshing在等待加载新数据时将此属性设为true,列表就会显示出一个正在加载的符号。
  • renderItem根据行数据data,渲染每一行的组件。这个参照下面的demo
  • viewabilityConfig请参考ViewabilityHelper 的源码来了解具体的配置。
  • 方法

    scrollToEnd
    滚动到底部。如果不设置getItemLayout
    属性的话,可能会比较卡。

    scrollToIndex
    滚动到指定index的item
    如果不设置getItemLayout
    属性的话,无法跳转到当前可视区域以外的位置。

    scrollToItem
    滚动到指定item,如果不设置getItemLayout
    属性的话,可能会比较卡。

    scrollToOffset
    滚动指定距离

    Demo:

    import React, {Component} from 'react';import { StyleSheet, View, FlatList, Text, Button,} from 'react-native';var ITEM_HEIGHT = 100;export default class FlatListDemo extends Component { _flatList; _renderItem = (item) => { var txt = '第' + item.index + '个' + ' title=' + item.item.title; var bgColor = item.index % 2 == 0 ? 'red' : 'blue'; return <Text style={[{flex:1,height:ITEM_HEIGHT,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'}}/>; } 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.scrollToEnd(); //this._flatList.scrollToIndex({viewPosition:0,index:8}); 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} //numColumns ={3} //columnWrapperStyle={{borderWidth:2,borderColor:'black',paddingLeft:20}} //horizontal={true} //getItemLayout={(data,index)=>( //{length: ITEM_HEIGHT, offset: (ITEM_HEIGHT+2) * index, index} //)} //onEndReachedThreshold={5} //onEndReached={(info)=>{ //console.warn(info.distanceFromEnd); //}} //onViewableItemsChanged={(info)=>{ //console.warn(info); //}} data={data}> </FlatList> </View> </View> ); }}const styles = StyleSheet.create({ txt: { textAlign: 'center', textAlignVertical: 'center', color: 'white', fontSize: 30, }});

    效果图:

    进阶使用

    在这里我准备了一份代码示例:

    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, }})

    运行效果如下:

    总结

    总体来说Flatlist还是比ListView用起来方便的,而且提供的功能更多。

    以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

    声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。

    相关文章