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 getJSON方法详细分析
Dec 26 Javascript
利用jquery动画特效和css打造的侧边弹出垂直导航
Apr 04 Javascript
js propertychange和oninput事件
Sep 28 Javascript
JS实现重新加载当前页面
Nov 29 Javascript
Vue数据驱动模拟实现4
Jan 12 Javascript
用 Vue.js 递归组件实现可折叠的树形菜单(demo)
Dec 25 Javascript
如何将你的AngularJS1.x应用迁移至React的方法
Feb 01 Javascript
vue+express 构建后台管理系统的示例代码
Jul 19 Javascript
vuex actions传递多参数的处理方法
Sep 18 Javascript
判断JavaScript中的两个变量是否相等的操作符
Dec 21 Javascript
vue cli3适配所有端方案的实现
Apr 13 Javascript
Vue 401配合Vuex防止多次弹框的案例
Nov 11 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/04/02 无线电
如何使用FireFox插件FirePHP调试PHP
2013/07/23 PHP
php/JS实现的生成随机密码(验证码)功能示例
2019/06/06 PHP
自适应图片大小的弹出窗口
2006/07/27 Javascript
基于jQuery的Tab选项框效果代码(插件)
2011/03/01 Javascript
javascript权威指南 学习笔记之null和undefined
2011/09/25 Javascript
jQuery教程 $()包装函数来实现数组元素分页效果
2013/08/13 Javascript
验证控件与Button的OnClientClick事件详细解析
2013/12/04 Javascript
解决window.opener=null;window.close(),只支持IE6不支持IE7,IE8的问题
2014/01/14 Javascript
jquery原创弹出层折叠效果点击折叠弹出一个层
2014/03/12 Javascript
js实现获取焦点后光标在字符串后
2014/09/17 Javascript
分析了一下JQuery中的extend方法实现原理
2015/02/27 Javascript
jQuery提示插件alertify使用指南
2015/04/21 Javascript
基于node实现websocket协议
2016/04/25 Javascript
JS常用加密编码与算法实例总结
2016/12/22 Javascript
JavaScript实现审核流程状态的动态显示进度条
2017/03/15 Javascript
jquery实现tab键进行选择后enter键触发click行为
2017/03/29 jQuery
AngularJs实现聊天列表实时刷新功能
2017/06/15 Javascript
详解angularJS+Ionic移动端图片上传的解决办法
2017/09/13 Javascript
vue 组件中slot插口的具体用法
2018/04/03 Javascript
详解mpvue开发小程序小总结
2018/07/25 Javascript
Vue加载组件、动态加载组件的几种方式
2018/08/31 Javascript
从零开始搭建vue移动端项目到上线的步骤
2018/10/15 Javascript
Node.js从字符串生成文件流的实现方法
2019/08/18 Javascript
详解Vue中CSS样式穿透问题
2019/09/12 Javascript
js实现3D旋转相册
2020/08/02 Javascript
python在TXT文件中按照某一字符串取出该字符串所在的行方法
2018/12/10 Python
Python面向对象程序设计类的多态用法详解
2019/04/12 Python
解决Python计算矩阵乘向量,矩阵乘实数的一些小错误
2019/08/26 Python
python对Excel按条件进行内容补充(推荐)
2019/11/24 Python
Django重设Admin密码过程解析
2020/02/10 Python
Python3的socket使用方法详解
2020/02/18 Python
Python调用jar包方法实现过程解析
2020/08/11 Python
实习推荐信
2014/05/10 职场文书
四风查摆剖析材料
2014/10/10 职场文书
python 经纬度求两点距离、三点面积操作
2021/06/03 Python