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

ActivityIndicator

这里上拉加载的转圈效果用ActivityIndicator表现。在开始上拉加载的实现之前先介绍一下官方组件ActivityIndicator——加载指示器。ActivityIndicator的使用很简单。

    <ActivityIndicatoranimating={true}color='red'size="large"/>

属性

属性 类型 描述
animating bool 是否要显示指示器,默认为true,表示显示。
color string 滚轮的前景颜色(默认为灰色)。
hidesWhenStopped(ios) bool 在没有动画的时候,是否要隐藏指示器(默认为true)。
size enum(‘small’, ‘large’) 指示器的大小。small的高度为20,large为36。

加载页

根据上述ActivityIndicator属性的介绍,可以使用ActivityIndicator实现一个简单的加载页面:

import React, {Component} from "react";
import {ActivityIndicator,  StyleSheet,  View} from "react-native";export default class ActivityIndicatorDemo extends Component {render() {return (<View style={styles.container}><ActivityIndicator
                    animating={true}color='red'size="large"/></View>);}
}const styles = StyleSheet.create({container: {flex: 1,flexDirection: 'row',justifyContent: 'center',alignItems: 'center',backgroundColor: '#F5FCFF',},
});

其效果如下:

上拉加载的实现

下面进入正篇——上拉加载的实现
上拉加载一般应用于分页加载的情况,为了真实的模拟网络请求数据上拉刷新加载更多的使用场景,这里使用github提供的api。

思路

当FlatList滑动到底部时,页面数加一,触发请求新一页的网络数据,更新到组件state中的数据源dataArray中,dataArray也作为FlatList的数据源data。实现滑动到底部触发网络请求通过FlatList的onEndReachedonEndReachedThreshold属性,onEndReached是在当列表被滚动到距离内容最底部不足onEndReachedThreshold的距离时调用。

具体实现

全局变量

const REQUEST_URL = 'https://api.github.com/search/repositories?q=javascript&sort=stars&page=';
let pageNo = 1;//当前第几页
let totalPage=5;//总的页数
let itemNo=0;//item的个数

初始化state

    constructor(props) {super(props);this.state = {isLoading: true,//网络请求状态error: false,errorInfo: "",dataArray: [],showFoot:0, // 控制foot, 0:隐藏footer  1:已加载完成,没有更多数据   2 :显示加载中isRefreshing:false,//下拉控制}}

网络请求——获取第n页数据

    //网络请求——获取第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();}

准备加载组件
在初始化state之后,渲染组件前,请求网络数据。

    componentDidMount() {//请求数据this.fetchData( pageNo );}

渲染组件

    render() {//第一次加载等待的viewif (this.state.isLoading && !this.state.error) {return this.renderLoadingView();} else if (this.state.error) {//请求失败viewreturn this.renderErrorView();}//加载数据return this.renderData();}

加载等待页
利用上面介绍的ActivityIndicator,实现加载等待页。

    renderLoadingView() {return (<View style={styles.container}><ActivityIndicator
                    animating={true}color='red'size="large"/></View>);}

加载网络请求失败页
网络请求失败,显示失败信息页。

    renderErrorView() {return (<View style={styles.container}><Text>Fail</Text></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}/>);}

每个item组件渲染
renderItem根据行数据data渲染每一行的组件。

    //返回itemView_renderItemView({item}) {return (<View><Text style={styles.title}>name: {item.value.name} ({item.value.stargazers_count}stars)</Text><Text style={styles.content}>description: {item.value.description}</Text></View>);}

尾部组件的渲染
ListFooterComponent为尾部组件的渲染
当showFoot为2时显示loading的动态效果是用ActivityIndicator来实现的。

     _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,当列表被滚动到距离内容最底部不足onEndReachedThreshold的距离时调用。注意:onEndReachedThreshold的值不是像素单位而是比值,例如,0.5表示距离内容最底部的距离为当前列表可见长度的一半时触发。

    _onEndReached(){//如果是正在加载中或没有更多数据了,则返回if(this.state.showFoot != 0 ){return ;}//如果当前页大于或等于总页数,那就是到最后一页了,返回if((pageNo!=1) && (pageNo>=totalPage)){return;} else {pageNo++;}//底部显示正在加载更多数据this.setState({showFoot:2});//获取数据this.fetchData( pageNo );}
}

分隔线
ItemSeparatorComponent行与行之间的分隔线组件,不会出现在第一行之前和最后一行之后。

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

效果图如下:

最后附上完整代码:

import React, {Component} from "react";
import {ActivityIndicator, FlatList, StyleSheet, Text, View} 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的个数
export default class LoadMoreDemo 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>);}//加载失败viewrenderErrorView() {return (<View style={styles.container}><Text>Fail</Text></View>);}//返回itemView_renderItemView({item}) {return (<View><Text style={styles.title}>name: {item.value.name}</Text><Text style={styles.content}>stars: {item.value.stargazers_count}</Text><Text style={styles.content}>description: {item.value.description}</Text></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() {//第一次加载等待的viewif (this.state.isLoading && !this.state.error) {return this.renderLoadingView();} else if (this.state.error) {//请求失败viewreturn 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',},title: {fontSize: 15,color: 'blue',},footer:{flexDirection:'row',height:24,justifyContent:'center',alignItems:'center',marginBottom:10,},content: {fontSize: 15,color: 'black',}
});

react native学习笔记13——FlatList上拉加载相关推荐

  1. react-native flatlist 上拉加载onEndReached方法频繁触发的问题

    问题 在写flatlist复用组件时,调用的时候如果父组件是不定高的组件,会造成组件无法显示 如果父组件样式{flex:1},则会出现下拉方法频繁触发或不正常触发的问题(我这里出现的问题是在列表第6个 ...

  2. React Native 实现FlatList的下拉刷新上拉加载

    RN对列表已经实现了下拉刷新与上拉加载的功能,但是为了更好用,做了封装. 实现的功能:     1.下拉刷新,使用原生下拉头.     2.上拉加载,自定义加载布局.     3.处理了重复刷新或重复 ...

  3. React Native 上拉加载

    实现的比较简单,原理就是在下一页有数据的情况下,ScrollView底部始终会有一个loading图表和加载中的文字,每次ScrollView滚动到底部时loading部分就会显示出来,然后去请求数据 ...

  4. React上拉加载和下拉刷新

    最近在做一个功能,就是上拉加载下一页,用的是react搭建前端视图,以下是我的做法和遇到的相关问题及解决办法: 案例一:回到顶部 class Home extends Component {consr ...

  5. react上拉加载更多

    react 前言 最近在写的项目中有上拉加载更多的需求.抽空就来写一篇文章. 上拉加载更多,下拉刷新,在原生 App 上经常都用到,既符合用户的使用习惯,也有很多成熟的库可以直接拿来使用.那么在Web ...

  6. React上拉加载(React-PullLoad)

    1.下载react-pullload npm i react-pullload 2.在组件中去引用 import ReactPullLoad,{ STATS } from "react-pu ...

  7. vue开发(三)vue-scroller实现下拉刷新,上拉加载笔记(包括吸顶效果失效的问题)

    项目中要实现下拉刷新,上拉加载,首先想到了vue-scroller. npm网址:vue-scroller 简单记录一下自己的使用过程,以备不时之需. 安装依赖: npm install vue-sc ...

  8. 【FastDev4Android框架开发】RecyclerView完全解析之下拉刷新与上拉加载SwipeRefreshLayout(三十一)...

    转载请标明出处: http://blog.csdn.net/developer_jiangqq/article/details/49992269 本文出自:[江清清的博客] (一).前言: [好消息] ...

  9. 分享轮子-flutter下拉刷新上拉加载

    flutter下拉上拉组件轮子 什么是flutter? 首先说下flutter,估计这个应该挺多人没听过flutter这个框架,它是一个google推出的跨平台的移动应用UI框架,和React Nat ...

最新文章

  1. [转]Android横竖屏切换解决方案
  2. 这个主板制作的是一样的吗?
  3. 解决ExcelReport导出Excel报Number of rules must not exceed 3错误的问题
  4. mysql error code 145,MYSQL 错误#145解决方法
  5. 【Unity】6.1 Unity中的C#脚本基础知识
  6. python学习-综合练习五(五人分鱼(优化解)、顺向、反向推导)
  7. 一个jdbc connection连接对应一个事务
  8. STL_算法_区间的比較(equal、mismatch、 lexicographical_compare)
  9. 一个技术预案,让老板当场喊出了“奥利给”
  10. c语言程序设计授课进度安排表,C语言程序设计教学大纲、教学计划进度简表
  11. python 列表 元祖 字典,Python 列表、元组、字典
  12. 力扣491. 递增子序列(JavaScript)
  13. mysql批量删除数据库_数据库实现批量删除数据的操作方法(代码实例)
  14. 中国人上淘宝喜欢干啥 你知道吗?
  15. 从3D Studio Max导入物体 Importing Objects From 3D Studio Max
  16. TCP/IP协议分层模型以及数据的封装和分用
  17. 利用OpenCV实现一个简单的实时人脸检测项目并显示FPS
  18. 家政服务app软件开发
  19. HTML横向二级导航
  20. 日本RPA工程师的现状和未来

热门文章

  1. python生成表格并显示在浏览器_Pyodide:在浏览器端实现Python全栈科学计算
  2. 关于JS代码风格(整理+自己的意见)
  3. getParameter的用法说明
  4. AI算法示例-图像识别
  5. centos gdb调试_Linux基础 30分钟GDB调试快速突破
  6. 移动端vw vh适配
  7. 详解缓存穿透、缓存雪崩、缓存击穿
  8. 关于cv2.imread()的使用
  9. 全球与中国超高真空 (UHV) 腔室市场现状及未来发展趋势
  10. make menuconfig跟踪