Maison > interface Web > js tutoriel > le corps du texte

Comment utiliser Native dans React pour implémenter un menu déroulant personnalisé afin d'actualiser la liste chargée par pull-up

亚连
Libérer: 2018-06-02 14:37:59
original
2574 Les gens l'ont consulté

Cet article présente principalement l'exemple de personnalisation du menu déroulant pour actualiser la liste déroulante chargée dans React Native. Maintenant, je le partage avec vous et le donne comme référence.

Les pages de liste sont des pages très courantes dans le développement mobile. Dans React Native, nous utilisons généralement les composants FlatList ou SectionList pour implémenter ces vues de liste. Habituellement, la page de liste contient une grande quantité de données qui doivent être chargées et affichées. À ce stade, le chargement de pagination est utilisé. Par conséquent, pour le composant de liste, il est essentiel d'implémenter l'actualisation déroulante et le chargement déroulant. de nombreux cas.

Cet article encapsule un RefreshListView qui prend en charge l'actualisation pull-down et le chargement pull-up basé sur FlatList. Après avoir encapsulé la FlatList d'origine, il est très pratique d'appeler l'actualisation pull-up et pull-down.

L'implémentation de l'actualisation déroulante est très simple. Ici, nous utilisons les propriétés de FlatList elle-même pour implémenter

onRefresh— Après avoir défini cette option, une norme sera ajouté en tête de liste du champ RefreshControl afin d'implémenter la fonction "pull-down rafraîchissement". Dans le même temps, vous devez définir correctement l'attribut d'actualisation.

refreshing—— valeur booléenne, utilisée pour contrôler l'affichage et le masquage du contrôle d'actualisation. Défini sur false une fois l'actualisation terminée.

En définissant ces deux propriétés, nous pouvons réaliser l'opération d'actualisation de l'en-tête FlatList. Le contrôle utilise le style par défaut, et Android et iOS utilisent les composants de leurs systèmes respectifs pour afficher.

Le point clé est d'extraire pour charger plus. Le composant de liste de React Native n'a pas cette fonction et nous devons l'implémenter nous-mêmes. Pour le chargement pull-up, nous avons généralement plusieurs états. Ici, je crée un fichier RefreshState.js pour stocker l'état de chargement pull-up :

export default {
 Idle: 'Idle',        // 初始状态,无刷新的情况
 CanLoadMore: 'CanLoadMore', // 可以加载更多,表示列表还有数据可以继续加载
 Refreshing: 'Refreshing',  // 正在刷新中
 NoMoreData: 'NoMoreData',  // 没有更多数据了
 Failure: 'Failure'     // 刷新失败
}
Copier après la connexion

Ensuite, j'encapsule un composant RefreshFooter basé sur ces états pour le créer. Différents contenus sont affichés selon différents états. Sans plus tarder, parlons du code :

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: &#39;row&#39;,
  justifyContent: &#39;center&#39;,
  alignItems: &#39;center&#39;,
  padding: 15,
 },
 refreshingText: {
  fontSize: 12,
  color: "#666666",
  paddingLeft: 10,
 },
 footerText: {
  fontSize: 12,
  color: "#666666"
 }
});
Copier après la connexion

Notez que propTypes est la méthode que nous définissons pour le composant RefreshFooter pour les appels externes. spécifié à l'aide de PropTypes et Facebook doit être installé. La bibliothèque de dépendances prop-types est mieux installée en utilisant Yarn Add Prop-Types, qui est moins sujette aux erreurs. Ceci est utilisé pour la vérification du type d'exécution. Vous pouvez cliquer ici pour en savoir plus.

Dans defaultProps, nous définissons plusieurs contenus de texte par défaut dans différents états, qui peuvent être modifiés en transmettant des valeurs en externe.

La prochaine étape consiste à implémenter ce RefreshListView. Tout d'abord, il doit être clair que ce RefreshListView doit avoir des méthodes d'appel d'actualisation de tête et d'actualisation de queue, et que la méthode spécifique d'appel des données doit être implémentée en externe. Définissez d'abord deux méthodes comme RefreshFooter :

static propTypes = {
 onHeaderRefresh: PropTypes.func, // 下拉刷新的方法,供外部调用
 onFooterRefresh: PropTypes.func, // 上拉加载的方法,供外部调用
};
Copier après la connexion

Comme mentionné ci-dessus, l'actualisation déroulante de la tête est implémentée à l'aide des propres fonctionnalités de FlatList. Nous devons définir une valeur booléenne isHeaderRefreshing comme valeur de l'attribut d'actualisation. pour contrôler l'en-tête affiché ou non. En même temps, définissez un isFooterRefreshing pour déterminer l'état d'actualisation du composant tail. Définissez footerState pour définir l’état du composant tail actuel comme valeur de RefreshFooter.

constructor(props) {
  super(props);
  this.state = {
   isHeaderRefreshing: false, // 头部是否正在刷新
   isFooterRefreshing: false, // 尾部是否正在刷新
   footerState: RefreshState.Idle, // 尾部当前的状态,默认为Idle,不显示控件
  }
 }
Copier après la connexion

La fonction de rendu est la suivante :

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()
    }}
   />
  )
 };
Copier après la connexion

Vous pouvez voir qu'il existe deux méthodes,beginHeaderRefresh etbeginFooterRefresh, dans le code ci-dessus.Ces deux méthodes sont utilisées pour appeler. actualiser, mais dans Il y a encore quelques situations logiques qui doivent être jugées avant d'actualiser. Par exemple, la tête et la queue ne peuvent pas être actualisées en même temps, sinon les résultats du traitement des données pourraient être affectés. Les opérations d'actualisation répétées doivent être évitées pendant l'actualisation. Ici, j'ai commenté en détail dans le code :

/// 开始下拉刷新
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;
}
Copier après la connexion

La logique de startHeaderRefreshing et startFooterRefreshing est la suivante :

/// 下拉刷新,设置完刷新状态后再调用刷新方法,使页面上可以显示出加载中的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();
  }
 );
}
Copier après la connexion

Avant d'actualiser, nous devons afficher les composants de tête ou de queue , puis appelez la méthode d'interface de données externe. L'avantage d'écrire setState ici est que les méthodes de la fonction fléchée ne seront appelées qu'une fois la valeur de l'état mise à jour. Si this.props.onFooterRefresh && this.props.onFooterRefresh() est écrit à l'extérieur. setState, Sur l'interface utilisateur, nous ne voyons peut-être pas le chargement dans la tête ou le chargement dur dans la queue, mais la méthode d'interface a déjà été appelée.

Enfin, une fois l'actualisation terminée, nous devons également appeler la méthode stop rafraîchissement afin que les composants de tête ou de queue ne soient plus affichés, sinon cela peut être considéré comme un bug s'il est toujours en chargement. Voyons comment arrêter l'actualisation :

/**
 * 根据尾部组件状态来停止刷新
 * @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
 })
}
Copier après la connexion

Le paramètre d'état d'un composant de queue est transmis ici pour mettre à jour le style du composant de queue. Dans le même temps, un jugement est porté sur les données de la source de données. Si elle est vide, cela signifie qu'il n'y a actuellement aucune donnée et qu'une page vierge peut être affichée. Il n'est alors pas nécessaire d'afficher le composant de queue.

Ce qui suit est le rendu du chargement des pages du film Douban que j'ai implémenté à l'aide de RefreshListView :

Ce qui précède est ce que j'ai compilé pour tout le monde. J'espère qu'il sera utile à tout le monde. avenir.

Articles associés :

Exemples de fonctions de déduplication d'ensemble, d'intersection, d'union et d'ensemble de différences implémentées par JS

le temps setTimeout est défini à 0 Analyse détaillée de

La méthode du fichier de configuration index.js dans le répertoire de configuration de l'échafaudage vue-cli

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal