React-Native实现ListView组件之上拉刷新实例(iOS和Android通用)


Posted in Javascript onJuly 11, 2017

在web应用中,上拉刷新加载更多,下拉刷新列表的操作非常常见,那么在React-Native中是如何实现呢,我们具体来看一下
ReactNative提供了RefreshControl下拉刷新组件,但是没有提供上拉刷新组件,上拉刷新在App中是很常用的。

今天我们来实现一个iOS和Android通用的上拉刷新功能。

下面简要介绍下我实现的思路。

思路:

1、常量定义:

const moreText = "加载完毕"; //foot显示的文案 
//页码 
var pageNum = 1; 
//每页显示数据的条数 
const pageSize = 10; 
//页面总数据数 
var pageCount = 0; 
//页面List总数据 
var totalList = new Array(); 
 
//foot: 0 隐藏 1 已加载完成 2 显示加载中

2、定义ListView

<ListView 
 enableEmptySections={true} 
 dataSource={this.state.dataSource} 
 renderRow={this._renderRow.bind(this)} 
 renderFooter={this._renderFooter.bind(this)} 
 onEndReached={this._endReached.bind(this)} 
 onEndReachedThreshold={0} 
/>

3、声明State状态机变量

ListView.DataSource实例(列表依赖的数据源)

constructor(props) { 
 super(props); 
 this.state = { 
  dataSource: new ListView.DataSource({ 
   rowHasChanged: (r1, r2) => r1 !== r2, 
  }), 
  loaded: false,//控制Request请求是否加载完毕 
  foot:0,// 控制foot, 0:隐藏foot 1:已加载完成 2 :显示加载中 
  error:false,

这里我们主要声明了dataSource,这个没什么说的

  1. loaded:用来控制整个页面的菊花
  2. error:如果Request错误,显示一个错误页面
  3. foot: 控制Footer的view

4、渲染页面前,加载数据

componentWillMount() { 
 this._fetchListData(); 
}

5、Load服务端数据

_fetchListData() { 
 if(pageNum > 1){ 
  this.setState({loaded:true}); 
 } 
 fetch(requestURL, { 
  method: 'get', 
  headers: headerObj, 
 }).then(response =>{ 
  if (response.ok) { 
   return response.json(); 
  } else { 
   this.setState({error:true,loaded:true}); 
  } 
 }).then(json=>{ 
  let responseCode = json.code; 
  if (responseCode == 0) { 
   let responseData = json.data; 
 
   pageCount = responseData.count; 
   let list = responseData.data; 
 
   if (orderList == null) { 
    orderList = []; 
    currentCount = 0; 
   } else { 
    currentCount = list.length; 
   } 
   if(currentCount < pageSize){ 
    //当当前返回的数据小于PageSize时,认为已加载完毕 
    this.setState({ foot:1,moreText:moreText}); 
   }else{//设置foot 隐藏Footer 
    this.setState({foot:0}); 
   } 
   for (var i=0; i < list.length; i++) { 
    totalList.push( list[i] ); 
   } 
 
   this.setState({ 
    dataSource: this.state.dataSource.cloneWithRows(totalList), 
    loaded: true, 
   }); 
  }else{ 
   this.setState({error:true,loaded:true}); 
  } 
 }).catch(function (error) { 
  this.setState({error:true,loaded:true}); 
 }); 
}

这里的细节挺多的:

1、当pageNum > 1时,就不要整个页面的菊花,此时loaded一直为true,这个主要是为了页面效果,要不然没加载一页数据,这个屏幕就会闪一下。

2、比较当前返回的list的大小,是否小于pageSize,控制Footer是否隐藏,还是显示已加载完毕

3、声明了一个全局的totalList对象,每次有新数据的时候,都push进去。

如果不采用push的方式的话,直接采用setState方法的话,第二页会把第一页的数据覆盖掉。

6、定义renderRow方法

renderRow={this._renderRow.bind(this)}   列表组件渲染函数 ,此处页面逻辑省略。

7、定义renderFooter方法

renderFooter   页脚会在每次渲染过程中都重新渲染。

_renderFooter() { 
 if(this.state.foot === 1){//加载完毕 
  return ( 
  <View style={{height:40,alignItems:'center',justifyContent:'flex-start',}}> 
   <Text style={{color:'#999999',fontSize:12,marginTop:10}}> 
    {this.state.moreText} 
   </Text> 
  </View>); 
 }else if(this.state.foot === 2) {//加载中 
  return ( 
  <View style={{height:40,alignItems:'center',justifyContent:'center',}}> 
   <Image source={{uri:loadgif}} style={{width:20,height:20}}/> 
  </View>); 
 } 
}

根据状态机变量foot控制Footer的显示

8、onEndReached 定义

onEndReachedThreshold={0}

当所有的数据都已经渲染过,并且列表被滚动到距离最底部不足onEndReachedThreshold个像素的距离时调用。原生的滚动事件会被作为参数传递。译注:当第一次渲染时,如果数据不足一屏(比如初始值是空的),这个事件也会被触发

_endReached(){ 
 if(this.state.foot != 0 ){ 
 return ; 
 } 
 this.setState({ 
 foot:2, 
 }); 
 this.timer = setTimeout( 
 () => { 
  pageNum ++; 
  this._fetchListData(); 
 },500); 
}

这里需要注意一下几点

1、第一屏的时候可能也会触发_endReached方法,所以需要判断foot为非 0(即加载中和已加载完毕)时,直接return

2、上拉时,触发_endReached方法,可能server端接口响应很快,几乎看不到菊花效果,特地加了个500毫秒的等待

9、卸载Timer

componentWillUnmount() { 
// 如果存在this.timer,则使用clearTimeout清空。 
// 如果你使用多个timer,那么用多个变量,或者用个数组来保存引用,然后逐个clear 
 this.timer && clearTimeout(this.timer); 
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
Apply an AutoFormat to an Excel Spreadsheet
Jun 12 Javascript
服务器端的JavaScript脚本 Node.js 使用入门
Mar 07 Javascript
IE下写xml文件的两种方式(fso/saveAs)
Aug 05 Javascript
jQuery探测位置的提示弹窗(toolTip box)详细解析
Nov 14 Javascript
js 定时器setTimeout无法调用局部变量的解决办法
Nov 28 Javascript
javascript实现单击和双击并存的方法
Dec 13 Javascript
JS实现快速的导航下拉菜单动画效果附源码下载
Nov 01 Javascript
js实现可以点击收缩或张开的悬浮窗
Sep 18 Javascript
详解vue移动端日期选择组件
Feb 22 Javascript
AngularJS 事件发布机制
Aug 28 Javascript
小程序自定义单页面、全局导航栏的实现代码
Mar 15 Javascript
vue vantUI tab切换时 list组件不触发load事件的问题及解决方法
Feb 14 Javascript
详解Webpack DLL用法以及功能
Jul 11 #Javascript
Bootstrap弹出框之自定义悬停框标题、内容和样式示例代码
Jul 11 #Javascript
node使用UEditor富文本编辑器的方法实例
Jul 11 #Javascript
Vue.js结合Ueditor富文本编辑器的实例代码
Jul 11 #Javascript
BootStrap Table复选框默认选中功能的实现代码(从数据库获取到对应的状态进行判断是否为选中状态)
Jul 11 #Javascript
JS自定义滚动条效果简单实现代码
Oct 27 #Javascript
jQuery实现节点的追加、替换、删除、复制功能示例
Jul 11 #jQuery
You might like
SONY ICF-SW55的电路分析
2021/03/02 无线电
使用PHP编写发红包程序
2015/07/22 PHP
ThinkPHP5与单元测试PHPUnit使用详解
2020/02/23 PHP
日期函数扩展类Ver0.1.1
2006/09/07 Javascript
Javascript的构造函数和constructor属性
2010/01/09 Javascript
百度Popup.js弹出框进化版 拖拽小框架发布 兼容IE6/7/8,Firefox,Chrome
2010/04/13 Javascript
理解Javascript_02_理解undefined和null
2010/10/11 Javascript
读jQuery之十三 添加事件和删除事件的核心方法
2011/08/23 Javascript
浅谈checkbox的一些操作(实战经验)
2013/11/20 Javascript
js拖动div 当鼠标移动时整个div也相应的移动
2013/11/21 Javascript
JavaScript将字符串转换为整数的方法
2015/04/14 Javascript
如何利用JSHint减少JavaScript的错误
2016/08/23 Javascript
Jquery+Ajax+xml实现中国地区选择三级联动菜单效果(推荐)
2017/06/09 jQuery
Angular中使用better-scroll插件的方法
2018/03/27 Javascript
新版vue-cli模板下本地开发环境使用node服务器跨域的方法
2018/04/03 Javascript
基于node+websocket+html实现腾讯课堂聊天室聊天功能
2020/03/04 Javascript
[04:42]5分钟带你了解什么是DOTA2(第一期)
2017/02/07 DOTA
浅谈Python2获取中文文件名的编码问题
2018/01/09 Python
Python实现动态图解析、合成与倒放
2018/01/18 Python
详解Python 定时框架 Apscheduler原理及安装过程
2019/06/14 Python
python实现对列表中的元素进行倒序打印
2019/11/23 Python
使paramiko库执行命令时在给定的时间强制退出功能的实现
2021/03/03 Python
html5教程实现Photoshop渐变色效果
2013/12/04 HTML / CSS
享受加州生活方式的时尚舒适:XCVI
2018/07/09 全球购物
帕克纽约:PARKER NY
2018/12/09 全球购物
澳大利亚当地社区首选的光学商店:1001 Optical
2019/08/24 全球购物
在对linux系统分区进行格式化时需要对磁盘簇(或i节点密度)的大小进行选择,请说明选择的原则
2012/01/13 面试题
护理自我鉴定范文
2013/10/06 职场文书
英语文学专业学生的自我评价
2013/10/31 职场文书
校友会欢迎辞
2014/01/13 职场文书
《夏夜多美》教学反思
2014/02/17 职场文书
大学生党员学习焦裕禄精神思想汇报
2014/09/10 职场文书
麦田里的守望者读书笔记
2015/06/30 职场文书
感谢信
2019/04/11 职场文书
加薪申请书应该这样写!
2019/07/04 职场文书
Mysql使用全文索引(FullText index)的实例代码
2022/04/03 MySQL