长列表(VirtualizedList,FlatList,SectionList,SwipeableFlatList)

10 12月

基于react-native v0.60+,为何要特意说明版本,你懂的~

  • VirtualizedList
  • FlatList
  • SectionList
  • SwipeableFlatList

VirtualizedList

早先RN的ListView已经被废弃了,因为ListView的渲染item是全量渲染,没有item的复用机制。例如后端返回50条数据,ListView会等50条全部渲染后一次性展示,这样内存占用较多,会出现卡顿。

现在RN推出FlatList的性能要高于ListView,靠的就是底层的VirtualizedList,它是FlatList,SectionList的底层实现,有item复用机制,离可视区域越近的item优先级越高。渲染窗口能响应滚动事件,所以当用户快速滚动时,会出现短暂空白。

用法和FlatList大同小异,看文档,不赘述。

FlatList

FlatList是最常用的基本长列表。支持自定义列表头尾,下拉刷新,上拉加载,多列布局等。Props:

data:数据,只支持普通数组,如果要用其他特殊数据结构,例如immutable数组,请直接使用更底层的VirtualizedList
renderItem:每个item的组件
ItemSeparatorComponent:item间分隔线组件
ListHeaderComponent:列表头组件
ListFooterComponent:列表底组件
ListEmptyComponent:列表为空时渲染该组件
onRefresh:下拉刷新时用,会在头部添加标准的RefreshControl小菊花组件
refreshing:下拉刷新时用,true时显示小菊花
onEndReached:上拉加载时用,当列表滚动到底部阀值时触发,例如发请求获取分页数据
onEndReachedThreshold:上拉加载时用,列表滚动到底部的阀值。是个比例值,不是像素,例如0.5表示距离底部为当前列表可见长度的一半时触发
getItemLayout:性能优化时用的,如果你能提前知道item高度,可以告知系统,避免系统动态计算行高(注意,如果设置了SeparatorComponent分隔线,也要计算进去)。这样可以节省系统动态计算内容行高的开销。当列表很长,如100+条数据时,可以大大提升渲染性能。
horizontal:设为true则水平布局
columnWrapperStyle:多列布局(即numColumns>1),可以额外指定此样式作用在每行容器上。
numColumns:多列布局的列数,只支持等高item,暂不支持瀑布流

import React, { Component } from 'react';
import { StyleSheet, Text, View, SafeAreaView, FlatList, } from 'react-native';

export default class FlatListDemo extends Component {
    constructor(props) {
        super(props);
        this.state = {
            isLoading: true,
            data: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"]
        }
    }

    _renderItem = ({item, index}) => {
        return <View style={{height: 120, backgroundColor: "skyblue"}}>
            <Text>{item}</Text>
        </View>
    }

    _ItemSeparatorComponent = () => {
        return <View style={{height:2, backgroundColor:"#000"}} />
    }

    _ListHeaderComponent = () => {
        return <View><Text>头部数据</Text></View>
    }

    _ListFooterComponent = () => {
        return <View><Text>我也是有底线的</Text></View>
    }

    _ListEmptyComponent = () => {
        return <View><Text>没有数据</Text></View>
    }

    _onRefresh = () => {

    }

    _onEndReached = () => {
        const newData = this.state.data.concat(this.state.data);
        this.setState({
            data: newData
        })
    }

    render() {
        return (
            <SafeAreaView style={styles.container}>
                <FlatList 
                    data={this.state.data}
                    renderItem={this._renderItem}
                    ItemSeparatorComponent={this._ItemSeparatorComponent}
                    ListHeaderComponent={this._ListHeaderComponent}
                    ListFooterComponent={this._ListFooterComponent}
                    ListEmptyComponent={this._ListEmptyComponent}
                    onRefresh={this._onRefresh} // 会在头部添加标准的 RefreshControl 小菊花组件,下拉刷新必备
                    refreshing={this.state.isLoading}   // 等待加载数据时,true:显示小菊花
                    onEndReached={this._onEndReached}     // 当列表滚动到底部不足多少时触发,用于上拉加载
                    onEndReachedThreshold={0.4}  // 是个比例值,不是像素,例如0.5表示距离底部距离为当前列表可见长度的一半时触发
                />
            </SafeAreaView>
        );
    }
}

SectionList

SectionList支持分组item。本质是基于VirtualizedList组件的封装,继承了其所有props(也包括所有ScrollView的props)。此外还有下面这些需要注意的事项:

用法和FlatList大同小异,看文档,不赘述。

SwipeableFlatList

支持手势滑动删除,这个在RN 0.5x某个版本支持了下,到0.6x版本又找不到了,估计被remove了(issue),本就是实验性组件。可以使用react-native-swipe-list-view

用法和FlatList大同小异,看文档,不赘述。

发表评论

电子邮件地址不会被公开。 必填项已用*标注