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 相关文章推荐
一个用js实现的页内搜索代码
May 23 Javascript
jquery获取元素值的方法(常见的表单元素)
Nov 15 Javascript
JavaScript动态操作表格实例(添加,删除行,列及单元格)
Nov 25 Javascript
在JavaScript中使用JSON数据
Feb 15 Javascript
jQ处理xml文件和xml字符串的方法(详解)
Nov 22 Javascript
vue.js删除动态绑定的radio的指定项
Jun 02 Javascript
js模块加载方式浅析
Aug 12 Javascript
javascript字体颜色控件的开发 JS实现字体控制
Nov 27 Javascript
jquery手机触屏滑动拼音字母城市选择器的实例代码
Dec 11 jQuery
我所理解的JavaScript中的this指向
Sep 04 Javascript
vue-cli3项目配置eslint代码规范的完整步骤
Sep 10 Javascript
Rust中的Struct使用示例详解
Aug 14 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中SESSION使用中的一点经验总结
2012/03/30 PHP
php生成zip压缩文件的方法详解
2013/06/09 PHP
ThinkPHP查询语句与关联查询用法实例
2014/11/01 PHP
php多次include后导致全局变量global失效的解决方法
2015/02/28 PHP
PHP使用glob方法遍历文件夹下所有文件的实例
2018/10/17 PHP
javascript innerHTML使用分析
2010/12/03 Javascript
让你的博文自动带上缩址的实现代码,方便发到微博客上
2010/12/28 Javascript
javascript中onclick(this)用法介绍
2013/04/19 Javascript
多个datatable共存造成多个表格的checkbox都被选中
2013/07/11 Javascript
JS中eval函数的使用示例
2013/07/21 Javascript
Chrome下ifame父窗口调用子窗口的问题示例探讨
2014/03/17 Javascript
一个html5播放视频的video控件只支持android的默认格式mp4和3gp
2014/05/08 Javascript
分享一个常用的javascript静态类
2014/12/31 Javascript
JavaScript数组合并的多种方法
2016/05/22 Javascript
浅谈Angularjs link和compile的使用区别
2016/10/21 Javascript
Bootstrap导航条的使用和理解3
2016/12/14 Javascript
Ajax异步获取html数据中包含js方法无效的解决方法
2017/02/20 Javascript
详解Angular 中 ngOnInit 和 constructor 使用场景
2017/06/22 Javascript
Angular模板表单校验方法详解
2017/08/11 Javascript
解决vue2.0动态绑定图片src属性值初始化时报错的问题
2018/03/14 Javascript
webpack css加载和图片加载的方法示例
2018/09/11 Javascript
vue实现一个炫酷的日历组件
2018/10/08 Javascript
详解vuex状态管理模式
2018/11/01 Javascript
一篇文章,教你学会Vue CLI 插件开发
2019/04/17 Javascript
微信小程序中target和currentTarget的区别小结
2020/11/06 Javascript
用virtualenv建立多个Python独立虚拟开发环境
2017/07/06 Python
Python方法的延迟加载的示例代码
2017/12/18 Python
Python利用openpyxl库遍历Sheet的实例
2018/05/03 Python
舞会礼服和舞会鞋:PromGirl
2019/04/22 全球购物
集世界奢侈品和设计师品牌的意大利精品买手店:Tessabit
2019/08/17 全球购物
施惠特软件测试面试题以及笔试题
2015/05/13 面试题
优秀演讲稿范文
2013/12/29 职场文书
幼儿园健康教育方案
2014/06/14 职场文书
债务纠纷委托书范本
2014/10/14 职场文书
公司欠款证明
2015/06/24 职场文书
Python作用域和名称空间的详细介绍
2022/04/13 Python