亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

React Native如何自定義下拉刷新上拉加載的列表

發布時間:2021-07-26 13:43:54 來源:億速云 閱讀:440 作者:小新 欄目:web開發

小編給大家分享一下React Native如何自定義下拉刷新上拉加載的列表,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

在移動端開發中列表頁是非常常見的頁面,在React Native中我們一般使用FlatList或SectionList組件實現這些列表視圖。通常列表頁都會有大量的數據需要加載顯示,這時候就用到了分頁加載,因此對于列表組件來說,實現下拉刷新和上拉加載在很多情況下是必不可少的。

本篇文章基于FlatList封裝一個支持下拉刷新和上拉加載的RefreshListView,對原始的FlatList進行封裝之后,再調用上拉和下拉刷新就十分方便了。

下拉刷新的實現十分簡單,這里我們沿用FlatList本身的屬性來實現

onRefresh— 設置此選項后,則會在列表頭部添加一個標準的RefreshControl控件,以便實現“下拉刷新”的功能。同時你需要正確設置refreshing屬性。

refreshing—— bool值,用來控制刷新控件的顯示與隱藏。刷新完成后設為false。

通過這兩個屬性設置我們就可以實現FlatList頭部的刷新操作,控件使用默認的樣式,Android和iOS沿用各自系統的組件來顯示。

重點在于上拉加載更多,React Native的列表組件中沒有這個功能,需要我們自己實現。 對于上拉加載,通常我們有幾種狀態,這里我創建一個RefreshState.js文件存放上拉加載的狀態:

export default {
 Idle: 'Idle',        // 初始狀態,無刷新的情況
 CanLoadMore: 'CanLoadMore', // 可以加載更多,表示列表還有數據可以繼續加載
 Refreshing: 'Refreshing',  // 正在刷新中
 NoMoreData: 'NoMoreData',  // 沒有更多數據了
 Failure: 'Failure'     // 刷新失敗
}

然后根據這幾種狀態來封裝一個RefreshFooter組件,使其根據不同狀態顯示不同內容,廢話不多說上代碼:

import React, {Component} from 'react';
import {View, Text, ActivityIndicator, StyleSheet, TouchableOpacity} from 'react-native';
import RefreshState from './RefreshState';
import PropTypes from 'prop-types';

export default class RefreshFooter extends Component {

 static propTypes = {
  onLoadMore: PropTypes.func,   // 加載更多數據的方法
  onRetryLoading: PropTypes.func, // 重新加載的方法
 };
 
 static defaultProps = {
  footerRefreshingText: "努力加載中",
  footerLoadMoreText: "上拉加載更多",
  footerFailureText: "點擊重新加載",
  footerNoMoreDataText: "已全部加載完畢"
 };
 
 render() {
  let {state} = this.props;
  let footer = null;
  switch (state) {
   case RefreshState.Idle:
    // Idle情況下為null,不顯示尾部組件
    break;
   case RefreshState.Refreshing:
    // 顯示一個loading視圖
    footer =
     <View style={styles.loadingView}>
      <ActivityIndicator size="small"/>
      <Text style={styles.refreshingText}>{this.props.footerRefreshingText}</Text>
     </View>;
    break;
   case RefreshState.CanLoadMore:
    // 顯示上拉加載更多的文字
    footer =
     <View style={styles.loadingView}>
      <Text style={styles.footerText}>{this.props.footerLoadMoreText}</Text>
     </View>;
    break;
   case RefreshState.NoMoreData:
    // 顯示沒有更多數據的文字,內容可以自己修改
    footer =
     <View style={styles.loadingView}>
      <Text style={styles.footerText}>{this.props.footerNoMoreDataText}</Text>
     </View>;
    break;
   case RefreshState.Failure:
    // 加載失敗的情況使用TouchableOpacity做一個可點擊的組件,外部調用onRetryLoading重新加載數據
    footer =
     <TouchableOpacity style={styles.loadingView} onPress={()=>{
      this.props.onRetryLoading && this.props.onRetryLoading();
     }}>
      <Text style={styles.footerText}>{this.props.footerFailureText}</Text>
     </TouchableOpacity>;
    break;
  }
  return footer;
 }
}

const styles = StyleSheet.create({
 loadingView: {
  flexDirection: 'row',
  justifyContent: 'center',
  alignItems: 'center',
  padding: 15,
 },
 refreshingText: {
  fontSize: 12,
  color: "#666666",
  paddingLeft: 10,
 },
 footerText: {
  fontSize: 12,
  color: "#666666"
 }
});

注意,propTypes是我們給RefreshFooter組件定義的給外部調用的方法,方法類型需要使用PropTypes來指定,需要安裝facebook的prop-types依賴庫,最好使用 yarn add prop-types 安裝,不容易出錯。這里用作運行時的類型檢查,可以點擊這里 詳細了解。

defaultProps中我們定義了幾種不同狀態下默認的文本內容,可以在外部傳值進行修改。

接下來就要來實現這個RefreshListView了。首先應該明確的是,這個RefreshListView要有頭部刷新和尾部刷新的調用方法,具體調用數據的方法應該在外部實現。先跟RefreshFooter一樣定義兩個方法:

static propTypes = {
 onHeaderRefresh: PropTypes.func, // 下拉刷新的方法,供外部調用
 onFooterRefresh: PropTypes.func, // 上拉加載的方法,供外部調用
};

上面說到頭部的下拉刷新使用FlatList自帶特性實現,我們需要定義一個bool值isHeaderRefreshing來作為refreshing屬性的值,控制頭部顯示與否。同時定義一個isFooterRefreshing來判斷尾部組件的刷新狀態。定義footerState用來設定當前尾部組件的state,作為RefreshFooter的值。

constructor(props) {
  super(props);
  this.state = {
   isHeaderRefreshing: false, // 頭部是否正在刷新
   isFooterRefreshing: false, // 尾部是否正在刷新
   footerState: RefreshState.Idle, // 尾部當前的狀態,默認為Idle,不顯示控件
  }
 }

render函數如下:

render() {
  return (
   <FlatList
    {...this.props}
    onRefresh={()=>{ this.beginHeaderRefresh() }}
    refreshing={this.state.isHeaderRefreshing}
    onEndReached={() => { this.beginFooterRefresh() }}
    onEndReachedThreshold={0.1} // 這里取值0.1(0~1之間不包括0和1),可以根據實際情況調整,取值盡量小
    ListFooterComponent={this._renderFooter}
   />
  )
 }
 
 _renderFooter = () => {
  return (
   <RefreshFooter
    state={this.state.footerState}
    onRetryLoading={()=>{
     this.beginFooterRefresh()
    }}
   />
  )
 };

可以看到上面的代碼中有beginHeaderRefresh和beginFooterRefresh兩個方法,這兩個方法就是用來調用刷新的,但是在刷新之前還有一些邏輯情況需要判斷。比如頭部和尾部不能夠同時刷新,不然數據處理結果可能受到影響,正在刷新時要防止重復的刷新操作,這些都是要考慮的。這里我在代碼中詳細注釋了:

/// 開始下拉刷新
beginHeaderRefresh() {
 if (this.shouldStartHeaderRefreshing()) {
  this.startHeaderRefreshing();
 }
}

/// 開始上拉加載更多
beginFooterRefresh() {
 if (this.shouldStartFooterRefreshing()) {
  this.startFooterRefreshing();
 }
}

/***
 * 當前是否可以進行下拉刷新
 * @returns {boolean}
 *
 * 如果列表尾部正在執行上拉加載,就返回false
 * 如果列表頭部已經在刷新中了,就返回false
 */
shouldStartHeaderRefreshing() {
 if (this.state.footerState === RefreshState.refreshing ||
  this.state.isHeaderRefreshing ||
  this.state.isFooterRefreshing) {
  return false;
 }
 return true;
}

/***
 * 當前是否可以進行上拉加載更多
 * @returns {boolean}
 *
 * 如果底部已經在刷新,返回false
 * 如果底部狀態是沒有更多數據了,返回false
 * 如果頭部在刷新,則返回false
 * 如果列表數據為空,則返回false(初始狀態下列表是空的,這時候肯定不需要上拉加載更多,而應該執行下拉刷新)
 */
shouldStartFooterRefreshing() {
 if (this.state.footerState === RefreshState.refreshing ||
  this.state.footerState === RefreshState.NoMoreData ||
  this.props.data.length === 0 ||
  this.state.isHeaderRefreshing ||
  this.state.isFooterRefreshing) {
  return false;
 }
 return true;
}

其中startHeaderRefreshing和startFooterRefreshing的邏輯如下:

/// 下拉刷新,設置完刷新狀態后再調用刷新方法,使頁面上可以顯示出加載中的UI,注意這里setState寫法
startHeaderRefreshing() {
 this.setState(
  {
   isHeaderRefreshing: true
  },
  () => {
   this.props.onHeaderRefresh && this.props.onHeaderRefresh();
  }
 );
}

/// 上拉加載更多,將底部刷新狀態改為正在刷新,然后調用刷新方法,頁面上可以顯示出加載中的UI,注意這里setState寫法
startFooterRefreshing() {
 this.setState(
  {
   footerState: RefreshState.Refreshing,
   isFooterRefreshing: true
  },
  () => {
   this.props.onFooterRefresh && this.props.onFooterRefresh();
  }
 );
}

在刷新之前,我們需要將頭部或尾部的組件顯示出來,然后再調用外部的數據接口方法。這里setState這樣寫的好處是state中的值更新完成后才會調用箭頭函數中的方法,是有嚴格順序的,如果把 this.props.onFooterRefresh && this.props.onFooterRefresh() 寫在setState外部,在UI上我們可能看不到頭部的loading或者尾部的努力加載中,接口方法就已經調用完畢了。

最后,在刷新結束后我們還需要調用停止刷新的方法,使頭部或尾部組件不再顯示,否則一直是加載中還可能讓人以為是bug。下面看看停止刷新的方法:

/**
 * 根據尾部組件狀態來停止刷新
 * @param footerState
 *
 * 如果刷新完成,當前列表數據源是空的,就不顯示尾部組件了。
 * 這里這樣做是因為通常列表無數據時,我們會顯示一個空白頁,如果再顯示尾部組件如"沒有更多數據了"就顯得很多余
 */
endRefreshing(footerState: RefreshState) {
 let footerRefreshState = footerState;
 if (this.props.data.length === 0) {
  footerRefreshState = RefreshState.Idle;
 }
 this.setState({
  footerState: footerRefreshState,
  isHeaderRefreshing: false,
  isFooterRefreshing: false
 })
}

這里傳入一個尾部組件狀態的參數是為了更新尾部組件的樣式。同時對數據源data進行一個判斷,如果為空說明當前沒有數據,可以顯示空白頁面,那么尾部組件也沒必要顯示了。

以上是“React Native如何自定義下拉刷新上拉加載的列表”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

逊克县| 九江县| 车险| 绵竹市| 德江县| 武山县| 垣曲县| 大同市| 西安市| 潜江市| 临漳县| 巧家县| 延吉市| 西吉县| 尉氏县| 甘肃省| 阳谷县| 合作市| 阿拉善左旗| 延寿县| 阳信县| 兰考县| 大悟县| 宜昌市| 玉山县| 高要市| 浦北县| 茂名市| 平阴县| 新巴尔虎左旗| 长沙县| 湖南省| 彰武县| 临西县| 凤庆县| 恩施市| 庆元县| 托克逊县| 北流市| 海晏县| 金山区|