zoukankan      html  css  js  c++  java
  • [RN] React Native 实现 FlatList上拉加载

     FlatList可以利用官方组件 RefreshControl实现下拉刷新功能,但官方没有提供相应的上拉加载的组件,因此在RN中实现上拉加载比下拉刷新要复杂一点。
    不过我们仍可以通过FlatListonEndReachedonEndReachedThreshold属性来实现相应效果。

    我们以github提供的api为例

     
    先查看效果:
     
     
    具体实现代码如下:
    import React, {Component} from "react";
    import {ActivityIndicator, FlatList, StyleSheet, Text, View, Image} from "react-native";
    
    const REQUEST_URL = 'https://api.github.com/search/repositories?q=javascript&sort=stars&page=';
    let pageNo = 1;//当前第几页
    let totalPage=5;//总的页数
    let itemNo=0;//item的个数
    
    class Home extends Component {
        constructor(props) {
            super(props);
            this.state = {
                isLoading: true,
                //网络请求状态
                error: false,
                errorInfo: "",
                dataArray: [],
                showFoot:0, // 控制foot, 0:隐藏footer  1:已加载完成,没有更多数据   2 :显示加载中
                isRefreshing:false,//下拉控制
            }
        }
    
        //网络请求——获取第pageNo页数据
        fetchData(pageNo) {
            //这个是js的访问网络的方法
            fetch(REQUEST_URL+pageNo)
                .then((response) => response.json())
                .then((responseData) => {
                    let data = responseData.items;
                    let dataBlob = [];
                    let i = itemNo;
    
                    data.map(function (item) {
                        dataBlob.push({
                            key: i,
                            value: item,
                        })
                        i++;
                    });
                    itemNo = i;
                    console.log("itemNo:"+itemNo);
                    let foot = 0;
                    if(pageNo>=totalPage){
                        foot = 1;//listView底部显示没有更多数据了
                    }
    
                    this.setState({
                        //复制数据源
                        dataArray:this.state.dataArray.concat(dataBlob),
                        isLoading: false,
                        showFoot:foot,
                        isRefreshing:false,
                    });
                    data = null;
                    dataBlob = null;
                })
                .catch((error) => {
                    this.setState({
                        error: true,
                        errorInfo: error
                    })
                })
                .done();
        }
    
        componentDidMount() {
            //请求数据
            this.fetchData( pageNo );
        }
    
        //加载等待页
        renderLoadingView() {
            return (
                <View style={styles.container}>
                    <ActivityIndicator
                        animating={true}
                        color='red'
                        size="large"
                    />
                </View>
            );
        }
    
        //加载失败view
        renderErrorView() {
            return (
                <View style={styles.container}>
                    <Text>
                        Fail
                    </Text>
                </View>
            );
        }
    
        //返回itemView
        _renderItemView({item}) {
            return (
                <View style={styles.itemBox}>
                    <View style={styles.leftArea}>
                         <Image style={styles.avatar} source={{uri:item.value.owner.avatar_url}} />
                    </View>
                    <View style={styles.rightArea}>
                        <Text style={styles.title}>{item.value.name}</Text>
                        <Text style={styles.desc}>{item.value.description}</Text>
                    </View>
                </View>
            );
        }
    
        renderData() {
            return (
    
                <FlatList
                    data={this.state.dataArray}
                    renderItem={this._renderItemView}
                    ListFooterComponent={this._renderFooter.bind(this)}
                    onEndReached={this._onEndReached.bind(this)}
                    onEndReachedThreshold={1}
                    ItemSeparatorComponent={this._separator}
                />
    
            );
        }
    
        render() {
            //第一次加载等待的view
            if (this.state.isLoading && !this.state.error) {
                return this.renderLoadingView();
            } else if (this.state.error) {
                //请求失败view
                console.log(this.state.error);
                console.log(this.state.errorInfo);
                return this.renderErrorView();
            }
            //加载数据
            return this.renderData();
        }
        
        _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.state.showFoot != 0 ){
                return ;
            }
            //如果当前页大于或等于总页数,那就是到最后一页了,返回
            if((pageNo!=1) && (pageNo>=totalPage)){
                return;
            } else {
                pageNo++;
            }
            //底部显示正在加载更多数据
            this.setState({showFoot:2});
            //获取数据
            this.fetchData( pageNo );
        }
    }
    
    const styles = StyleSheet.create({
        container: {
            flex: 1,
            flexDirection: 'row',
            justifyContent: 'center',
            alignItems: 'center',
            backgroundColor: '#F5FCFF',
        },
        itemBox: {
            flex:1,
            flexDirection:'row',
            paddingTop:8,
            paddingBottom:8,
            paddingLeft:6,
            paddingRight:6,
        },
        leftArea: {
            flex:1,
            justifyContent: 'center',
            alignItems: 'center',
        },
        avatar: {
            40,
            height:40,
        },
        rightArea: {
            flex:5,
            justifyContent: 'center',
            alignItems: 'center',
        },
        title: {
            fontSize: 15,
            color: 'blue',
        },
        desc: {
            fontSize: 15,
            color: 'black',
        },
        
    });
    
    module.exports = Home;

    本博客地址: wukong1688

    本文原文地址:https://www.cnblogs.com/wukong1688/p/10823970.html

    转载请著名出处!谢谢~~

     
  • 相关阅读:
    Docker 第一篇 认识Docker 的作用好处
    AspNetCoreApi 跨域处理
    VS 2017 发布:由于构建错误,发布失败
    iTerm2 cheatsheet (from github)
    find命令:忽略一个目录或者多个目录
    git push throws error: RPC failed; result=22, HTTP code = 411的解决办法
    sourceTree 一款图形化GIT工具
    生产力工具之vimwiki 和 calendar
    source : not found 原因及解决办法
    亚马逊开放机器学习系统源代码:挑战谷歌TensorFlow
  • 原文地址:https://www.cnblogs.com/wukong1688/p/10823970.html
Copyright © 2011-2022 走看看