欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

React-Native实现ListView组件之上拉刷新实例(iOS和Android通用)

程序员文章站 2023-02-24 10:53:18
在web应用中,上拉刷新加载更多,下拉刷新列表的操作非常常见,那么在react-native中是如何实现呢,我们具体来看一下 reactnative提供了refreshc...

在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); 
} 

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。