react native学习笔记13——FlatList上拉加载
我们可以利用官方组件RefreshControl
实现下拉刷新功能,但React Native官方没有提供相应的上拉加载的组件,因此在RN中实现上拉加载比下拉刷新要复杂一点。
虽然没有直接提供上拉加载的组件,不过我们仍可以通过FlatList的onEndReached与onEndReachedThreshold属性来实现相应效果。
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的onEndReached和onEndReachedThreshold属性,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上拉加载相关推荐
- react-native flatlist 上拉加载onEndReached方法频繁触发的问题
问题 在写flatlist复用组件时,调用的时候如果父组件是不定高的组件,会造成组件无法显示 如果父组件样式{flex:1},则会出现下拉方法频繁触发或不正常触发的问题(我这里出现的问题是在列表第6个 ...
- React Native 实现FlatList的下拉刷新上拉加载
RN对列表已经实现了下拉刷新与上拉加载的功能,但是为了更好用,做了封装. 实现的功能: 1.下拉刷新,使用原生下拉头. 2.上拉加载,自定义加载布局. 3.处理了重复刷新或重复 ...
- React Native 上拉加载
实现的比较简单,原理就是在下一页有数据的情况下,ScrollView底部始终会有一个loading图表和加载中的文字,每次ScrollView滚动到底部时loading部分就会显示出来,然后去请求数据 ...
- React上拉加载和下拉刷新
最近在做一个功能,就是上拉加载下一页,用的是react搭建前端视图,以下是我的做法和遇到的相关问题及解决办法: 案例一:回到顶部 class Home extends Component {consr ...
- react上拉加载更多
react 前言 最近在写的项目中有上拉加载更多的需求.抽空就来写一篇文章. 上拉加载更多,下拉刷新,在原生 App 上经常都用到,既符合用户的使用习惯,也有很多成熟的库可以直接拿来使用.那么在Web ...
- React上拉加载(React-PullLoad)
1.下载react-pullload npm i react-pullload 2.在组件中去引用 import ReactPullLoad,{ STATS } from "react-pu ...
- vue开发(三)vue-scroller实现下拉刷新,上拉加载笔记(包括吸顶效果失效的问题)
项目中要实现下拉刷新,上拉加载,首先想到了vue-scroller. npm网址:vue-scroller 简单记录一下自己的使用过程,以备不时之需. 安装依赖: npm install vue-sc ...
- 【FastDev4Android框架开发】RecyclerView完全解析之下拉刷新与上拉加载SwipeRefreshLayout(三十一)...
转载请标明出处: http://blog.csdn.net/developer_jiangqq/article/details/49992269 本文出自:[江清清的博客] (一).前言: [好消息] ...
- 分享轮子-flutter下拉刷新上拉加载
flutter下拉上拉组件轮子 什么是flutter? 首先说下flutter,估计这个应该挺多人没听过flutter这个框架,它是一个google推出的跨平台的移动应用UI框架,和React Nat ...
最新文章
- [转]Android横竖屏切换解决方案
- 这个主板制作的是一样的吗?
- 解决ExcelReport导出Excel报Number of rules must not exceed 3错误的问题
- mysql error code 145,MYSQL 错误#145解决方法
- 【Unity】6.1 Unity中的C#脚本基础知识
- python学习-综合练习五(五人分鱼(优化解)、顺向、反向推导)
- 一个jdbc connection连接对应一个事务
- STL_算法_区间的比較(equal、mismatch、 lexicographical_compare)
- 一个技术预案,让老板当场喊出了“奥利给”
- c语言程序设计授课进度安排表,C语言程序设计教学大纲、教学计划进度简表
- python 列表 元祖 字典,Python 列表、元组、字典
- 力扣491. 递增子序列(JavaScript)
- mysql批量删除数据库_数据库实现批量删除数据的操作方法(代码实例)
- 中国人上淘宝喜欢干啥 你知道吗?
- 从3D Studio Max导入物体 Importing Objects From 3D Studio Max
- TCP/IP协议分层模型以及数据的封装和分用
- 利用OpenCV实现一个简单的实时人脸检测项目并显示FPS
- 家政服务app软件开发
- HTML横向二级导航
- 日本RPA工程师的现状和未来