FlatList使用示例包含RefreshControl

强德厚
2023-12-01

FlatList属性介绍

  • ItemSeparatorComponent:分割线组件,
  • ListFooterComponent:结尾组件
  • ListHeaderComponent:头组件
  • data:列表数据
  • horizontal:设置为true则变为水平列表。
  • numColumns:列数 组件内元素必须是等高的,无法支持瀑布流布局
  • columnWrapperStyle:numColumns大于1时,设置每行的样式
  • getItemLayout:如果我们知道行高可以用此方法节省动态计算行高的开销。
  • refreshing:是否正在加载数据
  • onRefresh:设置此属性需要一个标准的 RefreshControl 控件,刷新数据
  • renderItem:渲染每个组件
  • onViewableItemsChanged:当一个新的Item渲染或者隐藏 的时候调用此方法。参数:info: {viewableItems: Array, changed: Array}
  • viewableItems:当前可见的Item,changed:渲染或者隐藏的Item。
  • scrollToEnd({params?: ?{animated?: ?boolean}}):滚动到末尾,如果不设置getItemLayout属性的话,可能会比较卡。
  • scrollToIndexparams: {animated?: ?boolean, index: number, viewPosition?: number}:滚动到制定的位置
  • scrollToOffset(params: {animated?: ?boolean, offset: number}):滚动到指定的偏移的位置。

RefreshControl属性介绍

  • onRefresh:开始刷新时调用
  • refreshing:设置为true显示指示器,false:隐藏。
  • colors(android):指示器颜色,可以多个,循环显示。
  • progressBackgroundColor(android):指示器背景颜色
  • size(android):值:[0,1]。指示器大小,默认1,0:large
  • progressViewOffset(android):指示器距离顶部的位置,默认0.
  • tintColor(ios):指示器颜色
  • title(ios):指示器下显示的文字
  • titleColor(ios):指示器下显示的文字的颜色

代码

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

const ITEM_HEIGHT = 100;

export default class FlatListDemo extends Component {
    _flatList;

    constructor(props) {
        super(props);
        this.state = {
            isRefreshing: false,
            isLoading: false,
            data: ['北京', '上海', '广州', '深圳', '杭州', '苏州', '成都', '武汉', '郑州', '洛阳', '厦门', '青岛', '拉萨'],
        };
    }

    _renderItem = (item) => {
        // 此处item的数据结构是{item:对应data数组中的每一项,index:data数组中每一项的下标,separators:{}}
        // console.warn(item);
        const txt = `第${item.index}个` + ` title=${item.item}`;
        const bgColor = item.index % 2 === 0 ? 'red' : 'blue';
        return <Text style={[
            { flex: 1, height: ITEM_HEIGHT, backgroundColor: bgColor },
            styles.txt,
        ]} key={item.index}>{txt}</Text>;
    }

    _header = () => <Text style={[styles.txt, { backgroundColor: 'black' }]}>这是头部</Text>

    _footer = () => <Text style={[styles.txt, { backgroundColor: 'black' }]}>这是尾部</Text>

    _separator = () => <View style={{ height: 2, backgroundColor: 'yellow' }}/>

    genIndicator = () => (this.state.isLoading && <View style={styles.indicatorContainer}>
        <ActivityIndicator
            style={styles.indicator}
            size='large'
            animating={true}
        />
        <Text style={{ textAlign: 'center' }}>正在加载更多</Text>
    </View>)

    loadData = () => {
        if (this.state.isLoading) return;
        this.setState({
            isLoading: true,
        });
        setTimeout(() => {
            this.setState({
                data: this.state.data.concat(1),
                isLoading: false,
            });
        }, 2000);
    }

    refreshData = () => {
        if (this.state.isLoading || this.state.isRefreshing) return;
        this.setState({ isRefreshing: true });
        setTimeout(() => {
            const newAry = this.state.data;
            newAry.unshift(1);
            this.setState({
                data: newAry,
                isRefreshing: false,
            });
        }, 2000);
    }

    _keyExtractor = (item, index) => {
        console.log(`${item}${index}`);
        return `${item}${index}`;
    }

    render() {
        // 根据data不同的赋值情况查看_renderItem中的item的值的结构
        // const data = ['北京', '上海', '广州', '深圳', '杭州', '苏州', '成都', '武汉', '郑州', '洛阳', '厦门', '青岛', '拉萨'];
        // for (let i = 0; i < 10; i++) {
        //     data.push({ key: i, title: `${i}` });
        // }

        const { data } = this.state;

        return (
            <View style={{ flex: 1 }}>
                <Button title='滚动到指定位置' onPress={() => {
                    // this._flatList.scrollToEnd();
                    // this._flatList.scrollToIndex({ viewPosition: 0, index: 1 });
                    this._flatList.scrollToOffset({ animated: true, offset: 200 });
                }}/>
                <View style={{ flex: 1 }}>
                    <FlatList
                        ref={flatList => this._flatList = flatList}

                        // // 设置组件头部
                        // ListHeaderComponent={this._header}

                        // 设置组件尾部,可以在尾部组件中定义上拉刷新的组件
                        // ListFooterComponent={this._footer}
                        ListFooterComponent={this.genIndicator}

                        // 设置组件分割线
                        ItemSeparatorComponent={this._separator}

                        // 根据data中的每项数据进行渲染
                        renderItem={this._renderItem}

                        // // 列数 组件内元素必须是等高的,无法支持瀑布流布局
                        // numColumns ={2}

                        // // numColumns大于1时,设置每行的样式
                        // columnWrapperStyle={{
                        //     borderWidth: 20,
                        //     borderColor: 'pink',
                        //     paddingLeft: 0,
                        // }}

                        // // 设置为true则变为水平列表
                        // horizontal={true}

                        // // 如果我们知道行高可以用此方法节省动态计算行高的开销,是一个可选的优化,注意如果你指定了SeparatorComponent,请把分隔线的尺寸也考虑到offset的计算之中。并且设置getItemLayout属性的话在滚动列表时不会卡顿
                        getItemLayout={(data, index) => (
                            { length: ITEM_HEIGHT, offset: (ITEM_HEIGHT + 2) * index, index }
                        )}

                        // // 当列表被滚动到距离内容最底部不足onEndReachedThreshold的距离时进行滚动加载调用onEndReached这个回调。注意此参数是一个比值而非像素单位。比如,0.5表示距离内容最底部的距离为当前列表可见长度的一半时触发。
                        // onEndReachedThreshold={1}
                        // onEndReached={(info) => {
                        //     // info:{distanceFromEnd:距离底部的距离}
                        //     // console.log(info);
                        //     // console.warn(info.distanceFromEnd);
                        //     this.loadData();
                        // }}

                        // 是否正在加载数据,在等待加载新数据时将此属性设为true,列表就会显示出一个正在加载的符号
                        refreshing={this.state.isRefreshing}

                        // 设置此属性需要一个标准的 RefreshControl 控件,刷新数据
                        onRefresh={() => {
                            this.refreshData();
                        }}
                        refreshControl={
                            <RefreshControl
                                progressBackgroundColor='pink'
                                refreshing={this.state.isRefreshing}
                                onRefresh={() => this.refreshData()}
                                tintColor="#ff0000"
                                title="Loading..."
                                titleColor="#00ff00"
                                size={0}
                                progressViewOffset={30}
                                colors={['#0000ff', '#ff0000', '#00ff00']}
                            />}

                        // onViewableItemsChanged={(info) => {
                        //     console.warn(info);
                        // }}

                        keyExtractor={this._keyExtractor}

                        // 列表数据
                        data={data}>
                    </FlatList>
                </View>

            </View>
        );
    }
}

const styles = StyleSheet.create({
    txt: {
        textAlign: 'center',
        textAlignVertical: 'center',
        color: 'white',
        fontSize: 30,
    },
    indicator: {
        color: 'red',
        margin: 10,
    },
});
 类似资料: