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 CSS修改学习第五章 给“上传”添加样式
Feb 19 Javascript
javascript在事件监听方面的兼容性小结
Apr 07 Javascript
JS判断不同分辨率调用不同的CSS样式文件实现思路及测试代码
Jan 23 Javascript
js实现的黑背景灰色二级导航菜单效果代码
Aug 24 Javascript
JS实现自定义状态栏动画文字效果示例
Oct 12 Javascript
教你用Cordova打包Vue项目的方法
Oct 17 Javascript
js实现文件上传功能 后台使用MultipartFile
Sep 08 Javascript
Web安全之XSS攻击与防御小结
Dec 13 Javascript
vue实现路由懒加载及组件懒加载的方式
Jun 11 Javascript
layui 实现table翻页滚动条位置保持不变的例子
Sep 05 Javascript
有关vue 开发钉钉 H5 微应用 dd.ready() 不执行问题及快速解决方案
May 09 Javascript
JS实现超级好看的鼠标小尾巴特效
Dec 01 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
全国FM电台频率大全 - 22 重庆市
2020/03/11 无线电
PHP查询网站的PR值
2013/10/30 PHP
简介PHP的Yii框架中缓存的一些高级用法
2016/03/29 PHP
PHP中Restful api 错误提示返回值实现思路
2016/04/12 PHP
laravel学习教程之存取器
2016/07/30 PHP
php中照片旋转 (orientation) 问题的正确处理
2017/02/16 PHP
PHP简单实现二维数组的矩阵转置操作示例
2017/11/24 PHP
jQuery EasyUI API 中文文档 - PropertyGrid属性表格
2011/11/18 Javascript
jQuery结合CSS制作动态的下拉菜单
2015/10/27 Javascript
JavaScript实现ASC转汉字及汉字转ASC的方法
2016/01/23 Javascript
javascript类型系统——undefined和null全面了解
2016/07/13 Javascript
使用Angular.js实现简单的购物车功能
2016/11/21 Javascript
JavaScript获取中英文混合字符串长度的方法示例
2017/02/04 Javascript
JavaScript实现动态增删表格的方法
2017/03/09 Javascript
Vue利用canvas实现移动端手写板的方法
2018/05/03 Javascript
详解超简单的react服务器渲染(ssr)入坑指南
2019/02/28 Javascript
JS实现简单的表格增删
2020/01/16 Javascript
[04:50]2019DOTA2高校联赛秋季赛四强集锦
2019/12/27 DOTA
Python图像处理库PIL的ImageFont模块使用介绍
2020/02/26 Python
python网络编程:socketserver的基本使用方法实例分析
2020/04/09 Python
Python 实现劳拉游戏的实例代码(四连环、重力四子棋)
2021/03/03 Python
css3中background新增的4个新的相关属性用法介绍
2013/09/26 HTML / CSS
HTML5 audio标签使用js进行播放控制实例
2015/04/24 HTML / CSS
光声世纪笔试题目
2012/08/25 面试题
什么是会话Bean
2015/05/14 面试题
竟聘演讲稿范文
2013/12/31 职场文书
幼儿评语大全
2014/04/30 职场文书
注册资产评估专业求职信
2014/07/16 职场文书
暑期学习心得体会
2014/09/02 职场文书
党员剖析材料范文
2014/09/30 职场文书
领导批评与自我批评范文
2014/10/16 职场文书
2014年政风行风自查自纠报告
2014/10/21 职场文书
店铺转让协议书
2014/12/02 职场文书
小学生毕业评语
2014/12/26 职场文书
医学生自荐信范文
2015/03/05 职场文书
剑指Offer之Java算法习题精讲二叉树专项训练
2022/03/21 Java/Android