美文网首页
Refreshlist下拉刷新组件封装

Refreshlist下拉刷新组件封装

作者: MasterPaul | 来源:发表于2023-09-22 00:49 被阅读0次
import React, {Component} from 'react';
import {ActivityIndicator, FlatList, RefreshControl, StyleSheet, Text, View} from 'react-native';
import PropTypes from 'prop-types'

// RefreshList.propTypes = {
//     onFetch: PropTypes.func,
//     initialData:PropTypes.array,
//     onChangeData:PropTypes.func,
//     renderItem:PropTypes.func,
//     firstShowSpinner:PropTypes.bool,
//     allowInitLoad:PropTypes.bool
// }


let totalPage=0;//总的页数

export default class RefreshList extends Component {


    constructor(props){
        super(props);

        this.state = {
            dataArray:props.initialData ?? [],
            showFoot:0, // 控制foot, 0:隐藏footer  1:已加载完成,没有更多数据   2 :显示加载中
            isRefreshing:false,//下拉控制
        };
        this.page = 1;


    }

    //组件挂载完成后执行的方法
    componentDidMount(){

        let { firstShowSpinner, allowInitLoad, onFetch } = this.props
        if (allowInitLoad) {
            if (firstShowSpinner) {
                this.onRefresh();
            } else {
                onFetch(1, this.refreshSuccess, this.refreshFail)
            }
        }
    }



    shouldComponentUpdate() {
        return true
    }

    /**
     * 下拉刷新 开始
     */
    onRefresh = async () => {

        let { onFetch, allowRefresh } = this.props;
        // this.refs && this.refs.scrollToOffset({animated:true, offset: 0 })
        if (allowRefresh) {
            this.setState({ isRefreshing: true })
        }
        onFetch(this.page, this.refreshSuccess, this.refreshFail)
    };

    /**
     * 刷新没有动画
     */
    refreshWithOutAnimate = () => {
        this.props.onFetch(1, this.refreshSuccess, this.refreshFail)
    }

    /**
     * 下拉刷新成功处理
     */
     refreshSuccess = (data,pageSize,pages) => {

         let foot = 0;
         totalPage = pages
         if(this.page>=totalPage){
             foot = 1;//listView底部显示没有更多数据了
         }
         this.setState({
             //复制数据源
             dataArray:data,
             showFoot:foot,
             isRefreshing:false,
         });
    }
    /**
     * 下拉刷新失败处理
     */
     refreshFail = (errorCode) => {
        this.setState({refreshing: false, loadError: true, errorCode })
    }


    /**
     * 列表数据发生变化后
     */
    onChangeData = () => {
        let {dataArray} = this.state;
        if (this.props.onChangeData) {
            this.props.onChangeData(dataArray )
        }
    };

    /**
     * 更新data数据
     */
     updateData = (dataRes) => {
        // console.log(dataRes)
        this.setState({ data: dataRes })
    };


    _keyExtractor = (item, index) => index;


    render() {

        return (
            <FlatList
                data={this.state.dataArray}
                renderItem={this.props.renderItem}
                ListFooterComponent={this._renderFooter.bind(this)}
                onEndReached={this._onEndReached.bind(this)}
                onEndReachedThreshold={0.2}
                ItemSeparatorComponent={this.props.showSeparator && this._separator}
                keyExtractor={this._keyExtractor}
                onScrollBeginDrag={() => {
                    // console.log('onScrollBeginDrag');
                    this.canAction = true;
                }}
                onScrollEndDrag={() => {
                    // console.log('onScrollEndDrag');
                    this.canAction = false;
                }}
                onMomentumScrollBegin={() => {
                    // console.log('onMomentumScrollBegin');
                    this.canAction = true;
                }}
                onMomentumScrollEnd={() => {
                    // console.log('onMomentumScrollEnd');
                    this.canAction = false;
                }}
                windowSize={300}
                //为刷新设置颜色
                refreshControl={
                    <RefreshControl
                        refreshing={this.state.isRefreshing}
                        onRefresh={this.onRefresh.bind(this)}//因为涉及到this.state
                        colors={['#ff0000', '#00ff00','#0000ff','#3ad564']}
                        progressBackgroundColor="#ffffff"
                    />
                }
                {...this.props}
            />
        );
    }



    _separator(){
        return <View style={{height:1,backgroundColor:'#999999'}}/>;
    }

    _renderFooter(){
        if (this.state.showFoot === 1) {
            return (
                <View style={{height:30,alignItems:'center',justifyContent:'flex-start',}}>
                    <Text style={{color:'#999999',fontSize:14,marginTop:5,marginBottom:5,}}>
                        没有更多数据了
                    </Text>
                </View>
            );
        } else if(this.state.showFoot === 2) {
            return (
                <View style={styles.footer}>
                    <ActivityIndicator />
                    <Text>正在加载更多数据...</Text>
                </View>
            );
        } else if(this.state.showFoot === 0){
            return (
                <View style={styles.footer}>
                    <Text></Text>
                </View>
            );
        }
    }

    _onEndReached(){
        if(!this.canAction) return
        console.log('end reach');
        //如果是正在加载中或没有更多数据了,则返回
        if(this.state.showFoot != 0 || this.state.isRefreshing ){
            return ;
        }
        //如果当前页大于或等于总页数,那就是到最后一页了,返回
        if((this.page!=1) && (this.page>=totalPage)){
            return;
        } else {
            this.page++;
        }
        //底部显示正在加载更多数据
        this.setState({showFoot:2});
        //获取数据,在componentDidMount()已经请求过数据了
        if (this.page>1){
            this.props.onFetch(this.page, this.loadMoreSuccess, this.loadMoreFail)
        }
    }

    /**
     * 加载更多成功处理
     */
    loadMoreSuccess = (resData, pageSize = 10) => {
        let { dataArray } = this.state;

        let foot = 0
        if (resData.length < pageSize || resData.length == 0) {
            foot = 1
        }
        let merData = [...dataArray, ...resData]

        this.setState({ dataArray: merData, showFoot: foot }, () => {
            this.onChangeData();
        });
    }

    /**
     * 加载更多失败处理
     */
    loadMoreFail = (errorCode) => {
        console.log(errorCode);
        this.setState({ showFoot: 0 })

    }
}


const styles = StyleSheet.create({
    container: {
        flex: 1
    },
    center:{
        justifyContent:'center',alignItems: 'center'
    },
    oneBtn: {
        padding: 5,
        borderRadius: 5,
    },
    oneBox: {
        flexDirection: 'row',
        alignItems: 'center',
    },
    footer:{
        flexDirection: 'row',
        justifyContent: 'center',
        alignItems: 'center',
        paddingVertical:10
    }
});

相关文章

网友评论

      本文标题:Refreshlist下拉刷新组件封装

      本文链接:https://www.haomeiwen.com/subject/yoxtbdtx.html