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 密码强弱度检测万能插件
Feb 25 Javascript
js创建对象的几种常用方式小结(推荐)
Oct 24 Javascript
使用Firebug对js进行断点调试的图文方法
Apr 02 Javascript
JQuery中DOM加载与事件执行实例分析
Jun 13 Javascript
jQuery实现响应鼠标背景变化的动态菜单效果代码
Aug 27 Javascript
JS实现最简单的冒泡排序算法
Feb 15 Javascript
Angular2 之 路由与导航详细介绍
May 26 Javascript
详解ionic本地相册、拍照、裁剪、上传(单图完全版)
Oct 10 Javascript
JavaScript中Object基础内部方法图
Feb 05 Javascript
详解Vue SSR( Vue2 + Koa2 + Webpack4)配置指南
Nov 13 Javascript
如何提升vue.js中大型数据的性能
Jun 21 Javascript
5分钟快速看懂ES6中的反射与代理
Dec 19 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 和 XML: 使用expat函数(二)
2006/10/09 PHP
PHP导出带样式的Excel示例代码
2016/08/28 PHP
thinkPHP线上自动加载异常与修复方法实例分析
2016/12/01 PHP
PHP新特性详解之命名空间、性状与生成器
2017/07/18 PHP
JavaScript开发时的五个注意事项
2007/12/08 Javascript
textarea中的手动换行处理的jquery代码
2011/02/26 Javascript
浏览器页面区域大小的js获取方法
2013/09/21 Javascript
js弹出层永远居中实现思路及代码
2013/11/29 Javascript
jQuery中extend()和fn.extend()方法详解
2015/06/03 Javascript
不得不分享的JavaScript常用方法函数集(上)
2015/12/23 Javascript
jQuery实现点击关注和取消功能
2017/07/03 jQuery
jQuery动态添加.active 实现导航效果代码思路详解
2017/08/29 jQuery
浅谈webpack打包生成的bundle.js文件过大的问题
2018/02/22 Javascript
深入浅析nuxt.js基于ssh的vue通用框架
2019/05/21 Javascript
一文快速了解JQuery中的AJAX
2019/05/31 jQuery
JS实现横向轮播图(初级版)
2020/06/24 Javascript
jQuery实现简单评论功能
2020/08/19 jQuery
[01:15:18]2014 DOTA2国际邀请赛中国区预选赛 LGD VS Speed Gaming.cn
2014/05/22 DOTA
[02:31]《DAC最前线》之选手酒店现场花絮
2015/01/30 DOTA
[00:30]明星选手化身超级英雄!2018DOTA2亚洲邀请赛全明星赛来临!
2018/04/06 DOTA
python求pi的方法
2014/10/08 Python
Python用户推荐系统曼哈顿算法实现完整代码
2017/12/01 Python
Python之web模板应用
2017/12/26 Python
在pandas多重索引multiIndex中选定指定索引的行方法
2018/11/16 Python
Django框架实现的分页demo示例
2019/05/25 Python
淘宝秒杀python脚本 扫码登录版
2019/09/19 Python
python爬虫中PhantomJS加载页面的实例方法
2020/11/12 Python
css3 position fixed固定居中问题解决方案
2014/08/19 HTML / CSS
物业公司采购员岗位职责
2013/12/31 职场文书
优秀团干部个人事迹
2014/05/29 职场文书
初中学习计划书范文
2014/09/15 职场文书
2014年四风个人对照检查及整改措施
2014/10/28 职场文书
2015年司法局工作总结
2015/05/22 职场文书
七年级之家长会发言稿范文
2019/09/04 职场文书
Python 中面向接口编程
2022/05/20 Python
JS前端轻量fabric.js系列之画布初始化
2022/08/05 Javascript