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 相关文章推荐
基于jQuery的图片剪切插件
Aug 03 Javascript
国外大牛IE版本检测!现在IE都到9了,IE检测代码
Jan 04 Javascript
jquery实现图片预加载
Dec 25 Javascript
js中常用的Tab切换效果(推荐)
Aug 30 Javascript
vue中用动态组件实现选项卡切换效果
Mar 25 Javascript
Bootstrap开发中Tab标签页切换图表显示问题的解决方法
Jul 13 Javascript
如何使用puppet替换文件中的string
Dec 06 Javascript
通过JavaScript下载文件到本地的方法(单文件)
Mar 17 Javascript
Layui选项卡制作历史浏览记录的方法
Sep 28 Javascript
如何手写简易的 Vue Router
Oct 10 Javascript
vue集成一个支持图片缩放拖拽的富文本编辑器
Jan 29 Vue.js
介绍一下28个JS常用数组方法
May 06 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
php对gzip文件或者字符串解压实例参考
2008/07/25 PHP
phpphp图片采集后按原路径保存图片示例
2014/02/18 PHP
php实现只保留mysql中最新1000条记录
2015/06/18 PHP
php+ajax制作无刷新留言板
2015/10/27 PHP
深入理解PHP中的empty和isset函数
2016/05/26 PHP
在 Laravel 中 “规范” 的开发短信验证码发送功能
2017/10/26 PHP
Thinkphp5框架实现图片、音频和视频文件的上传功能详解
2019/08/27 PHP
js时间日期和毫秒的相互转换
2013/02/22 Javascript
用循环或if语句从json中取数据示例
2014/08/18 Javascript
javascript实现网页屏蔽Backspace事件,输入框不屏蔽
2015/07/21 Javascript
简介EasyUI datagrid editor combogrid搜索框的实现
2016/04/01 Javascript
JavaScript之生成器_动力节点Java学院整理
2017/06/30 Javascript
Vue响应式原理深入解析及注意事项
2017/12/11 Javascript
详解React之父子组件传递和其它一些要点
2018/06/25 Javascript
基于webpack4.X从零搭建React脚手架的方法步骤
2018/12/23 Javascript
微信小程序websocket实现即时聊天功能
2019/05/21 Javascript
[42:39]老党炸弹人试玩视频
2014/09/03 DOTA
浅谈python抛出异常、自定义异常, 传递异常
2016/06/20 Python
python如何获取服务器硬件信息
2017/05/11 Python
Django数据库操作的实例(增删改查)
2017/09/04 Python
Python3.4实现远程控制电脑开关机
2018/02/22 Python
树莓派用python中的OpenCV输出USB摄像头画面
2019/06/22 Python
python读写csv文件方法详细总结
2019/07/05 Python
python 实现GUI(图形用户界面)编程详解
2019/07/17 Python
Django发送邮件和itsdangerous模块的配合使用解析
2019/08/10 Python
python编写计算器功能
2019/10/25 Python
Python注释、分支结构、循环结构、伪“选择结构”用法实例分析
2020/01/09 Python
PyTorch中Tensor的数据统计示例
2020/02/17 Python
详解Python修复遥感影像条带的两种方式
2020/02/23 Python
银行职业规划书范文
2013/12/28 职场文书
交通事故委托书范本
2014/09/28 职场文书
教师学习群众路线心得体会
2014/11/04 职场文书
2015年圣诞节活动总结
2015/03/24 职场文书
新娘婚礼致辞
2015/07/27 职场文书
JS异步堆栈追踪之为什么await胜过Promise
2021/04/28 Javascript
mysql配置SSL证书登录的实现
2021/09/04 MySQL