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 相关文章推荐
javascript 设置某DIV区域内的checkbox复选框
Nov 30 Javascript
jquery $.getJSON()跨域请求
Dec 21 Javascript
js时间比较示例分享(日期比较)
Mar 05 Javascript
Javascript 运动中Offset的bug解决方案
Dec 24 Javascript
JQuery插件Quicksand实现超炫的动画洗牌效果
May 03 Javascript
JS实现的简单鼠标跟随DiV层效果完整实例
Oct 31 Javascript
jQuery根据表单name获取值的方法
May 24 Javascript
Bootstrap学习笔记之css组件(3)
Jun 07 Javascript
微信小程序 欢迎界面开发的实例详解
Nov 30 Javascript
vue2.0结合DataTable插件实现表格动态刷新的方法详解
Mar 17 Javascript
简单谈谈axios中的get,post方法
Jun 25 Javascript
Vue是怎么渲染template内的标签内容的
Jun 05 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
动漫女神老婆无限好,但日本女生可能就不是这么一回事了!
2020/03/04 日漫
兼容PHP5的PHP目录管理函数库
2008/07/10 PHP
php快速url重写更新版[需php 5.30以上]
2010/04/25 PHP
php判断某个方法是否存在函数function_exists (),method_exists()与is_callable()区别与用法解析
2020/04/20 PHP
通过js脚本复制网页上的一个表格的不错实现方法
2006/12/29 Javascript
js监听输入框值的即时变化onpropertychange、oninput
2011/07/13 Javascript
javascript限制文本框只允许输入数字(曾经与现在的方法对比)
2013/01/18 Javascript
javascript游戏开发之《三国志曹操传》零部件开发(二)人物行走的实现
2013/01/23 Javascript
JavaScript的递归之递归与循环示例介绍
2013/08/05 Javascript
用jQuery实现的智能隐藏、滑动效果的返回顶部代码
2014/03/18 Javascript
javascript为下拉列表动态添加数据项
2014/05/23 Javascript
JavaScript实现表格点击排序的方法
2015/05/11 Javascript
前端学习笔记style,currentStyle,getComputedStyle的用法与区别
2016/05/28 Javascript
angularjs 中$apply,$digest,$watch详解
2016/10/13 Javascript
微信小程序Server端环境配置详解(SSL, Nginx HTTPS,TLS 1.2 升级)
2017/01/12 Javascript
深入理解ES6学习笔记之块级作用域绑定
2017/08/19 Javascript
es6数据变更同步到视图层的方法
2019/03/04 Javascript
微信小程序页面滚动到指定位置代码实例
2019/09/07 Javascript
vue实现列表拖拽排序的功能
2020/11/02 Javascript
[11:01]2014DOTA2西雅图邀请赛 冷冷带你探秘威斯汀
2014/07/08 DOTA
python读文件逐行处理的示例代码分享
2013/12/27 Python
简单介绍使用Python解析并修改XML文档的方法
2015/10/15 Python
python实现折半查找和归并排序算法
2017/04/14 Python
详解python使用递归、尾递归、循环三种方式实现斐波那契数列
2018/01/16 Python
详解Python字典小结
2018/10/20 Python
使用pyshp包进行shapefile文件修改的例子
2019/12/06 Python
python实现udp聊天窗口
2020/03/31 Python
使用Python操作MySQL的小技巧
2020/09/10 Python
HTML5的新特性(1)
2016/03/03 HTML / CSS
企业车辆管理制度
2014/01/24 职场文书
2014年国庆节演讲稿
2014/09/19 职场文书
2014年优质护理服务工作总结
2014/11/14 职场文书
清洁工岗位职责
2015/02/13 职场文书
催款律师函范文
2015/05/27 职场文书
nginx配置proxy_pass中url末尾带/与不带/的区别详解
2021/03/31 Servers
Pytorch DataLoader shuffle验证方式
2021/06/02 Python