RN筆記-ListView上拉加載更多功能

React-Native中使用ListView時(shí)一般都會(huì)用到下拉刷新和上拉加載更多功能,系統(tǒng)提供有RefreshControl下拉刷新組件丢氢,簡(jiǎn)單易用傅联。
在做上拉加載更多功能時(shí)卻比較麻煩,在仔細(xì)研究了ReactNative官網(wǎng)文檔之后疚察,依然沒有找到實(shí)現(xiàn)辦法蒸走,但是可以了解到上拉加載功能肯定離不開ListView的兩個(gè)屬性onEndReachedonEndReachedThreshold貌嫡。

官網(wǎng)文檔中同時(shí)提到了renderFooter頁(yè)腳渲染屬性比驻,網(wǎng)上搜到的很多也用到了這個(gè)屬性该溯,但是我在使用過程中發(fā)現(xiàn)它對(duì)我并沒有幫助

onEndReached

當(dāng)所有的數(shù)據(jù)都已經(jīng)渲染過,并且列表被滾動(dòng)到距離最底部不足onEndReachedThreshold個(gè)像素的距離時(shí)調(diào)用别惦。原生的滾動(dòng)事件會(huì)被作為參數(shù)傳遞狈茉。譯注:當(dāng)?shù)谝淮武秩緯r(shí),如果數(shù)據(jù)不足一屏(比如初始值是空的)掸掸,這個(gè)事件也會(huì)被觸發(fā)氯庆,請(qǐng)自行做標(biāo)記過濾。

onEndReachedThreshold

調(diào)用onEndReached之前的臨界值猾漫,單位是像素点晴。

下面記錄我在實(shí)現(xiàn)上拉加載功能的具體方法和代碼。首先自定義正在加載更多和已加載全部的組件悯周,新建LoadMoreFooter.js文件粒督,復(fù)制粘貼以下代碼。

import React, { Component } from 'react';
  import {
      View,
      Text,
      StyleSheet,
      ActivityIndicator
  } from 'react-native';

  var LoadMoreFooter = React.createClass ({
      getDefaultProps(){
        return{
          isLoadAll:false
        }
      },
      render() {
          return (
              <View style={styles.footer}>
                  <ActivityIndicator animating={!this.props.isLoadAll} />
                  <Text style={styles.footerTitle}>{this.props.isLoadAll ? '已加載全部' : '正在加載更多…'}</Text>
              </View>
          )
      }
  })

  var styles = StyleSheet.create({
      footer: {
          flexDirection: 'row',
          justifyContent: 'center',
          alignItems: 'center',
          height: 30,
      },
      footerTitle: {
          marginLeft: 10,
          fontSize: 13,
          color: 'gray'
      }
  })

module.exports = LoadMoreFooter;

接下來(lái)要處理自定義加載更多組件的顯示與隱藏邏輯禽翼。當(dāng)this.state.isLoadMore ==true時(shí)顯示<LoadMoreFooter />組件屠橄,否則為null

  render() {
    return (
        this.state.isEmptyData ?
        this.isEmptyData() :
        <View style={styles.container}>
          { /*列表*/ }
          <ListView
            dataSource={this.state.dataSource}
            renderRow={this.renderRow}
            onEndReached={this._toEnd}
            onEndReachedThreshold={10}
            // renderFooter={this._toEnd}
            refreshControl={
             <RefreshControl
             refreshing={this.state.isRefreshing}
             tintColor="gray"
             title="正在刷新"
             onRefresh={this._onRefresh}/>}
          />
          {
            this.state.isLoadMore ?
            <LoadMoreFooter isLoadAll={!this.state.isLoadMore} />
            : null
          }
      </View>
    );
  },

下面要處理的是加載數(shù)據(jù)時(shí)最復(fù)雜的邏輯關(guān)系:刷新當(dāng)前數(shù)據(jù)、還是加載更多數(shù)據(jù)闰挡。這里定義了this.state.isRefreshing屬性來(lái)區(qū)分是否正在刷新當(dāng)前數(shù)據(jù)锐墙。同時(shí)定義了this.state.data屬性,當(dāng)正在加載更多數(shù)據(jù)時(shí)长酗,需要在當(dāng)前頁(yè)列表dataSource的基礎(chǔ)上追加下一頁(yè)的數(shù)據(jù)溪北,即[...this.state.data , ...JSON.parse(responseData).data]

向動(dòng)態(tài)數(shù)組中添加對(duì)象夺脾,使用的是方法是[...array_one , ...array_two]之拨,與OC中的可變數(shù)組不同。

  getInitialState(){
    //創(chuàng)建數(shù)據(jù)源
    var ds = new ListView.DataSource({rowHasChanged:(row1, row2) => row1 !== row2});
    //初始化數(shù)據(jù)源
    return {
      data:null,
      dataSource: ds,
      isEmptyData:false,
      isRefreshing:true,
      extend:'',
      isLoadMore:false,
      page:1
    }
  },

  //當(dāng)列表滑動(dòng)到最后一個(gè)Cell時(shí)咧叭,調(diào)用此方法
  _toEnd(){
    if (this.state.isRefreshing==false && this.state.data.length>=_pageSize) {
      this.setState({
        isLoadMore:true,
      })
      // 立即更改屬性值 page+1
      this.state.page = this.state.page + 1
      // 網(wǎng)絡(luò)請(qǐng)求數(shù)據(jù)
      this.getEduData();
    }
  },

注意事項(xiàng):
react native setState之后的state值不能立即使用蚀乔,setState之后,需要走完RN生命周期菲茬,也就是走到render時(shí)吉挣,state的值才會(huì)變成setState的值,要立即使用state的值婉弹,需要直接更改睬魂,也即this.state.something = 'now';
所以在設(shè)置page頁(yè)碼加1時(shí),不能直接在setState中設(shè)置镀赌,要實(shí)現(xiàn)page屬性立刻加1汉买,使用this.state.page = this.state.page + 1

數(shù)據(jù)請(qǐng)求成功后,要在請(qǐng)求成功的回調(diào)方法中更新數(shù)據(jù)源佩脊。使用三木運(yùn)算來(lái)分別更新刷新頁(yè)面數(shù)據(jù)蛙粘、和加載更多數(shù)據(jù)時(shí)的業(yè)務(wù)邏輯垫卤。

    // 更新數(shù)據(jù)源
    var data = this.state.data;
    if (!JSON.parse(responseData).data || JSON.parse(responseData).data.length==0) {
      this.setState({
        isEmptyData: this.state.isLoadMore ? false : true,
        isRefreshing:false,
        isLoadMore:false
      });
      if (this.state.isLoadMore) {
        // 立即更改屬性值 page-1
        this.state.page = this.state.page - 1
      }
    } else {
      data = this.state.isLoadMore ? [...this.state.data , ...JSON.parse(responseData).data] : JSON.parse(responseData).data
      this.setState({
        data:data,
        isRefreshing:false,
        dataSource:this.state.dataSource.cloneWithRows(data),
        isLoadMore:false,
      });
    }

如果請(qǐng)求的數(shù)據(jù)為空,展示給用戶提示信息出牧。

  isEmptyData(){
    return (
      <ScrollView style={{backgroundColor:'#e8e8e8'}}>
        <View style={styles.emptyDataStyle}>
          <Image source={{uri:'bv_dropbox'}} style={styles.emptyDataIcon}/>
          <Text style={{marginTop:5,color:'gray'}}>暫未有資訊</Text>
        </View>
      </ScrollView>
    )
  }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末穴肘,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子舔痕,更是在濱河造成了極大的恐慌评抚,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,427評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件伯复,死亡現(xiàn)場(chǎng)離奇詭異慨代,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)啸如,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門侍匙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人叮雳,你說(shuō)我怎么就攤上這事想暗。” “怎么了帘不?”我有些...
    開封第一講書人閱讀 165,747評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵说莫,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我寞焙,道長(zhǎng)储狭,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,939評(píng)論 1 295
  • 正文 為了忘掉前任捣郊,我火速辦了婚禮辽狈,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘模她。我一直安慰自己,他們只是感情好懂牧,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評(píng)論 6 392
  • 文/花漫 我一把揭開白布侈净。 她就那樣靜靜地躺著,像睡著了一般僧凤。 火紅的嫁衣襯著肌膚如雪畜侦。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,737評(píng)論 1 305
  • 那天躯保,我揣著相機(jī)與錄音旋膳,去河邊找鬼。 笑死途事,一個(gè)胖子當(dāng)著我的面吹牛验懊,可吹牛的內(nèi)容都是我干的擅羞。 我是一名探鬼主播,決...
    沈念sama閱讀 40,448評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼义图,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼减俏!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起碱工,我...
    開封第一講書人閱讀 39,352評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤娃承,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后怕篷,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體历筝,經(jīng)...
    沈念sama閱讀 45,834評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評(píng)論 3 338
  • 正文 我和宋清朗相戀三年廊谓,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了梳猪。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,133評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蹂析,死狀恐怖舔示,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情电抚,我是刑警寧澤惕稻,帶...
    沈念sama閱讀 35,815評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站蝙叛,受9級(jí)特大地震影響俺祠,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜借帘,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評(píng)論 3 331
  • 文/蒙蒙 一蜘渣、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧肺然,春花似錦蔫缸、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至街望,卻和暖如春校翔,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背灾前。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工防症, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,398評(píng)論 3 373
  • 正文 我出身青樓蔫敲,卻偏偏與公主長(zhǎng)得像饲嗽,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子燕偶,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容