欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

React Native 自定義下拉刷新上拉加載的列表的示例

 更新時(shí)間:2018年03月01日 09:16:48   作者:不變旋律  
本篇文章主要介紹了React Native 自定義下拉刷新上拉加載的列表的示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧

在移動(dòng)端開(kāi)發(fā)中列表頁(yè)是非常常見(jiàn)的頁(yè)面,在React Native中我們一般使用FlatList或SectionList組件實(shí)現(xiàn)這些列表視圖。通常列表頁(yè)都會(huì)有大量的數(shù)據(jù)需要加載顯示,這時(shí)候就用到了分頁(yè)加載,因此對(duì)于列表組件來(lái)說(shuō),實(shí)現(xiàn)下拉刷新和上拉加載在很多情況下是必不可少的。

本篇文章基于FlatList封裝一個(gè)支持下拉刷新和上拉加載的RefreshListView,對(duì)原始的FlatList進(jìn)行封裝之后,再調(diào)用上拉和下拉刷新就十分方便了。

下拉刷新的實(shí)現(xiàn)十分簡(jiǎn)單,這里我們沿用FlatList本身的屬性來(lái)實(shí)現(xiàn)

onRefresh— 設(shè)置此選項(xiàng)后,則會(huì)在列表頭部添加一個(gè)標(biāo)準(zhǔn)的RefreshControl控件,以便實(shí)現(xiàn)“下拉刷新”的功能。同時(shí)你需要正確設(shè)置refreshing屬性。

refreshing—— bool值,用來(lái)控制刷新控件的顯示與隱藏。刷新完成后設(shè)為false。

通過(guò)這兩個(gè)屬性設(shè)置我們就可以實(shí)現(xiàn)FlatList頭部的刷新操作,控件使用默認(rèn)的樣式,Android和iOS沿用各自系統(tǒng)的組件來(lái)顯示。

重點(diǎn)在于上拉加載更多,React Native的列表組件中沒(méi)有這個(gè)功能,需要我們自己實(shí)現(xiàn)。 對(duì)于上拉加載,通常我們有幾種狀態(tài),這里我創(chuàng)建一個(gè)RefreshState.js文件存放上拉加載的狀態(tài):

export default {
 Idle: 'Idle',        // 初始狀態(tài),無(wú)刷新的情況
 CanLoadMore: 'CanLoadMore', // 可以加載更多,表示列表還有數(shù)據(jù)可以繼續(xù)加載
 Refreshing: 'Refreshing',  // 正在刷新中
 NoMoreData: 'NoMoreData',  // 沒(méi)有更多數(shù)據(jù)了
 Failure: 'Failure'     // 刷新失敗
}

然后根據(jù)這幾種狀態(tài)來(lái)封裝一個(gè)RefreshFooter組件,使其根據(jù)不同狀態(tài)顯示不同內(nèi)容,廢話不多說(shuō)上代碼:

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,   // 加載更多數(shù)據(jù)的方法
  onRetryLoading: PropTypes.func, // 重新加載的方法
 };
 
 static defaultProps = {
  footerRefreshingText: "努力加載中",
  footerLoadMoreText: "上拉加載更多",
  footerFailureText: "點(diǎn)擊重新加載",
  footerNoMoreDataText: "已全部加載完畢"
 };
 
 render() {
  let {state} = this.props;
  let footer = null;
  switch (state) {
   case RefreshState.Idle:
    // Idle情況下為null,不顯示尾部組件
    break;
   case RefreshState.Refreshing:
    // 顯示一個(gè)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:
    // 顯示沒(méi)有更多數(shù)據(jù)的文字,內(nèi)容可以自己修改
    footer =
     <View style={styles.loadingView}>
      <Text style={styles.footerText}>{this.props.footerNoMoreDataText}</Text>
     </View>;
    break;
   case RefreshState.Failure:
    // 加載失敗的情況使用TouchableOpacity做一個(gè)可點(diǎn)擊的組件,外部調(diào)用onRetryLoading重新加載數(shù)據(jù)
    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組件定義的給外部調(diào)用的方法,方法類(lèi)型需要使用PropTypes來(lái)指定,需要安裝facebook的prop-types依賴(lài)庫(kù),最好使用 yarn add prop-types 安裝,不容易出錯(cuò)。這里用作運(yùn)行時(shí)的類(lèi)型檢查,可以點(diǎn)擊這里 詳細(xì)了解。

defaultProps中我們定義了幾種不同狀態(tài)下默認(rèn)的文本內(nèi)容,可以在外部傳值進(jìn)行修改。

接下來(lái)就要來(lái)實(shí)現(xiàn)這個(gè)RefreshListView了。首先應(yīng)該明確的是,這個(gè)RefreshListView要有頭部刷新和尾部刷新的調(diào)用方法,具體調(diào)用數(shù)據(jù)的方法應(yīng)該在外部實(shí)現(xiàn)。先跟RefreshFooter一樣定義兩個(gè)方法:

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

上面說(shuō)到頭部的下拉刷新使用FlatList自帶特性實(shí)現(xiàn),我們需要定義一個(gè)bool值isHeaderRefreshing來(lái)作為refreshing屬性的值,控制頭部顯示與否。同時(shí)定義一個(gè)isFooterRefreshing來(lái)判斷尾部組件的刷新?tīng)顟B(tài)。定義footerState用來(lái)設(shè)定當(dāng)前尾部組件的state,作為RefreshFooter的值。

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

render函數(shù)如下:

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

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

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

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

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

/***
 * 當(dāng)前是否可以進(jìn)行上拉加載更多
 * @returns {boolean}
 *
 * 如果底部已經(jīng)在刷新,返回false
 * 如果底部狀態(tài)是沒(méi)有更多數(shù)據(jù)了,返回false
 * 如果頭部在刷新,則返回false
 * 如果列表數(shù)據(jù)為空,則返回false(初始狀態(tài)下列表是空的,這時(shí)候肯定不需要上拉加載更多,而應(yīng)該執(zhí)行下拉刷新)
 */
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的邏輯如下:

/// 下拉刷新,設(shè)置完刷新?tīng)顟B(tài)后再調(diào)用刷新方法,使頁(yè)面上可以顯示出加載中的UI,注意這里setState寫(xiě)法
startHeaderRefreshing() {
 this.setState(
  {
   isHeaderRefreshing: true
  },
  () => {
   this.props.onHeaderRefresh && this.props.onHeaderRefresh();
  }
 );
}

/// 上拉加載更多,將底部刷新?tīng)顟B(tài)改為正在刷新,然后調(diào)用刷新方法,頁(yè)面上可以顯示出加載中的UI,注意這里setState寫(xiě)法
startFooterRefreshing() {
 this.setState(
  {
   footerState: RefreshState.Refreshing,
   isFooterRefreshing: true
  },
  () => {
   this.props.onFooterRefresh && this.props.onFooterRefresh();
  }
 );
}

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

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

/**
 * 根據(jù)尾部組件狀態(tài)來(lái)停止刷新
 * @param footerState
 *
 * 如果刷新完成,當(dāng)前列表數(shù)據(jù)源是空的,就不顯示尾部組件了。
 * 這里這樣做是因?yàn)橥ǔA斜頍o(wú)數(shù)據(jù)時(shí),我們會(huì)顯示一個(gè)空白頁(yè),如果再顯示尾部組件如"沒(méi)有更多數(shù)據(jù)了"就顯得很多余
 */
endRefreshing(footerState: RefreshState) {
 let footerRefreshState = footerState;
 if (this.props.data.length === 0) {
  footerRefreshState = RefreshState.Idle;
 }
 this.setState({
  footerState: footerRefreshState,
  isHeaderRefreshing: false,
  isFooterRefreshing: false
 })
}

這里傳入一個(gè)尾部組件狀態(tài)的參數(shù)是為了更新尾部組件的樣式。同時(shí)對(duì)數(shù)據(jù)源data進(jìn)行一個(gè)判斷,如果為空說(shuō)明當(dāng)前沒(méi)有數(shù)據(jù),可以顯示空白頁(yè)面,那么尾部組件也沒(méi)必要顯示了。

以下是我使用RefreshListView實(shí)現(xiàn)的豆瓣電影頁(yè)面分頁(yè)加載的效果圖:

完整的Demo地址: https://github.com/mrarronz/react-native-blog-examples/tree/master/Chapter4-PullRefresh/PullRefreshExample

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • react實(shí)現(xiàn)todolist的增刪改查詳解

    react實(shí)現(xiàn)todolist的增刪改查詳解

    這篇文章主要為大家介紹了react實(shí)現(xiàn)todolist的增刪改查,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2021-12-12
  • React狀態(tài)更新的優(yōu)先級(jí)機(jī)制源碼解析

    React狀態(tài)更新的優(yōu)先級(jí)機(jī)制源碼解析

    這篇文章主要為大家介紹了React狀態(tài)更新的優(yōu)先級(jí)機(jī)制源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • React onBlur回調(diào)中使用document.activeElement返回body完美解決方案

    React onBlur回調(diào)中使用document.activeElement返回body完美解決方案

    這篇文章主要介紹了React onBlur回調(diào)中使用document.activeElement返回body完美解決方案,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-04-04
  • react中實(shí)現(xiàn)修改input的defaultValue

    react中實(shí)現(xiàn)修改input的defaultValue

    這篇文章主要介紹了react中實(shí)現(xiàn)修改input的defaultValue方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • React?如何向url中添加參數(shù)

    React?如何向url中添加參數(shù)

    這篇文章主要介紹了React?如何向url中添加參數(shù),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • react-draggable實(shí)現(xiàn)拖拽功能實(shí)例詳解

    react-draggable實(shí)現(xiàn)拖拽功能實(shí)例詳解

    這篇文章主要給大家介紹了關(guān)于react-draggable實(shí)現(xiàn)拖拽功能的相關(guān)資料,React-Draggable一個(gè)使元素可拖動(dòng)的簡(jiǎn)單組件,文中通過(guò)代碼示例介紹的非常詳細(xì),需要的朋友可以參考下
    2023-08-08
  • redux的原理、工作流程及其應(yīng)用方式

    redux的原理、工作流程及其應(yīng)用方式

    這篇文章主要介紹了redux的原理、工作流程及其應(yīng)用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • 路由react-router-dom的基本使用教程

    路由react-router-dom的基本使用教程

    在React中,路由是一套映射規(guī)則,是URL路徑與組件的對(duì)應(yīng)關(guān)系。使用React路由,就是配置路徑和組件的對(duì)應(yīng)關(guān)系,這篇文章主要介紹了路由react-router-dom的使用,需要的朋友可以參考下
    2023-02-02
  • 使用VScode 插件debugger for chrome 調(diào)試react源碼的方法

    使用VScode 插件debugger for chrome 調(diào)試react源碼的方法

    這篇文章主要介紹了使用VScode 插件debugger for chrome 調(diào)試react源碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • React實(shí)現(xiàn)歌詞滾動(dòng)效果(跟隨音樂(lè)播放時(shí)間滾動(dòng))

    React實(shí)現(xiàn)歌詞滾動(dòng)效果(跟隨音樂(lè)播放時(shí)間滾動(dòng))

    這篇文章主要為大家詳細(xì)介紹了React實(shí)現(xiàn)歌詞滾動(dòng)效果(跟隨音樂(lè)播放使勁按滾動(dòng)),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2024-02-02

最新評(píng)論