1. 程式人生 > >ReactNative ListView + 上拉載入更多 + 下拉重新整理

ReactNative ListView + 上拉載入更多 + 下拉重新整理

ListView + 上拉載入更多 + 下拉重新整理

一、內容簡介

ListView列表在添加了上拉載入更多功能之後再新增下拉重新整理

二、程式碼實現

1、引入原生元件 RefreshControl

import { ListView, View, Text, ActivityIndicator, RefreshControl } from 'react-native';
注:RefreshControl 元件是RN原生的下拉重新整理元件,可應用與ListView和ScrollView

2、修改構造方法

增加狀態機:
isRefreshing:用來控制下拉重新整理

this.state = {
      demoList:  ds.cloneWithRows([]),
      isLoadingTail: false,
      isRefreshing: false,
      isNoMoreData: false
    };

3、修改render方法

增加下拉重新整理元件

render() {
    return (
      <ListView
        enableEmptySections={true}
        dataSource={this.state.demoList}
        renderRow={(rowData)
=>
this._renderRow(rowData)} renderFooter={() => this._renderFooter()} onEndReached={() => this._endReached()} onEndReachedThreshold={20} refreshControl={ <RefreshControl refreshing={this.state.isRefreshing} onRefresh={() =>
this._onRefresh()}/> } /> ); }

4、修改fetchData方法

重點:新增isLoadMore、isFirst標記

isFirst:標記是否是第一次進入該頁面,即初始化載入
isLoadMore:標記區分下拉重新整理和下拉載入更多

fetchData(isFirst, isLoadMore) {
    let page;

    if(isLoadMore) { // 上拉載入更多
      // 取出頁碼
      page = this.demoListPageInde[0];
      // 修改載入狀態
      this.setState({ isLoadingTail: true });
    } else { // 下拉重新整理
      // 重新整理時頁碼始終是1
      page = 1;
      // 第一次載入資料時不開啟重新整理機制
      if(!isFirst) {
        this.setState({
          isRefreshing: true
        });
      }
    }

    let url = 'http://travel.9797168.com/user/tips/getDynamicTips?type=45&p=' + page + '&num=10';
    fetch(url, {
      method: 'GET',
      headers: {},
    })
    .then((response)=>{
      if(response.ok){
        return response.json();
      }
    })
    .then((responseJson)=>{
      if(responseJson.status == 1) {
        let responseData = responseJson.data;

        if(responseData.length != 0) {
          if(isLoadMore) { // 上拉載入更多
            // 清空增量資料快取陣列
            this.cachedDemoList = [];
            // 儲存新的增量資料
            this.cachedDemoList = this.cachedDemoList.concat(responseData);

            // 將新資料追加到舊資料中
            this.demoList = this.demoList.concat(responseData);
            // 頁數+1
            this.demoListPageInde[0] += 1;

            // 預設每十條為一頁,不足十條,則說明沒有更多資料
            if(responseData.length < 10) {
              this.setState({
                isNoMoreData: true
              });
            }
          } else { // 下拉重新整理
            if(!isFirst) {
              // 清空資料記憶體儲存陣列
              this.demoList = [];

              // 重置頁數儲存陣列
              this.demoListPageInde[0] = 1;
            }

            // 儲存資料
            this.demoList = this.demoList.concat(responseData)

            // 自增
            this.demoListPageInde[0] += 1;
          }

          // 利用 immutability-helper 更新狀態機
          this.setState((previousState) => {
            var newState = update(previousState, {demoList:{
              $set: ds.cloneWithRows(this.demoList)
            }});
            return newState;
          });
        } else {
          if(isLoadMore) {
            // 清空增量資料快取陣列
            this.cachedDemoList = [];

            // TODO 提示沒有更多資料
          } else {
            // TODO 第一次載入或者下拉重新整理
          }
        }

        // 修改載入狀態
        if(isLoadMore) {
          // 關閉載入狀態
          this.setState({
            isLoadingTail: false
          });
        } else {
          // TODO 可區分是否是第一次載入
          this.setState({
            isRefreshing: false
          });
        }
      }
    })
    .catch((error)=>{
      // 修改載入狀態
      if(isLoadMore) {
        // 關閉載入狀態
        this.setState({
          isLoadingTail: false
        });
      } else {
        // TODO 可區分是否是第一次載入
        this.setState({
          isRefreshing: false
        });
      }
    });
  }

5、修改_endReached方法

_endReached = () => {
    // 防止重複申請
    if(this.state.isLoadingTail) {
      return
    }

    // 獲取資料
    this.fetchData(false, true);
  }

6、建立_onRefresh方法

_onRefresh = () => {
    // 當載入到最後一頁資料,再次下拉重新整理時,需關閉isNoMoreData狀態機
    this.setState({
      isNoMoreData: false
    });

    this.fetchData(false, false);
  }

7、修改componentDidMount生命週期中的方法

this.fetchData(true, false);