在React中使用Native如何实现自定义下拉刷新上拉加载的列表

本篇文章主要介绍了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 =                 {this.props.footerRefreshingText}     ;    break;   case RefreshState.CanLoadMore:    // 显示上拉加载更多的文字    footer =           {this.props.footerLoadMoreText}     ;    break;   case RefreshState.NoMoreData:    // 显示没有更多数据的文字,内容可以自己修改    footer =           {this.props.footerNoMoreDataText}     ;    break;   case RefreshState.Failure:    // 加载失败的情况使用TouchableOpacity做一个可点击的组件,外部调用onRetryLoading重新加载数据    footer =     {      this.props.onRetryLoading && this.props.onRetryLoading();     }}>      {this.props.footerFailureText}     ;    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 (   { this.beginHeaderRefresh() }}    refreshing={this.state.isHeaderRefreshing}    onEndReached={() => { this.beginFooterRefresh() }}    onEndReachedThreshold={0.1} // 这里取值0.1(0~1之间不包括0和1),可以根据实际情况调整,取值尽量小    ListFooterComponent={this._renderFooter}   />  ) }  _renderFooter = () => {  return (   {     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进行一个判断,如果为空说明当前没有数据,可以显示空白页面,那么尾部组件也没必要显示了。

以下是我使用RefreshListView实现的豆瓣电影页面分页加载的效果图:

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

JS实现的集合去重,交集,并集,差集功能示例

setTimeout时间设置为0详细解析

vue-cli脚手架config目录下index.js配置文件的方法

以上就是在React中使用Native如何实现自定义下拉刷新上拉加载的列表的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2750631.html

(0)
上一篇 2025年3月8日 05:39:38
下一篇 2025年3月8日 05:39:49

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • 怎样操作node实现登录图片验证码

    这次给大家带来怎样操作node实现登录图片验证码,操作node实现登录图片验证码的注意事项有哪些,下面就是实战案例,一起来看一下。 1.安装 cnpm i svg-captcha –save 登录后复制 2.在使用的地方导入 var sv…

    2025年3月8日 编程技术
    200
  • 怎样实现React diff算法

    这次给大家带来怎样实现React diff算法,实现React diff算法的注意事项有哪些,下面就是实战案例,一起来看一下。 前言 在上一篇文章,我们已经实现了React的组件功能,从功能的角度来说已经实现了React的核心功能了。 但是…

    2025年3月8日
    200
  • 怎样使用Vue实现proxy代理

    这次给大家带来怎样使用Vue实现proxy代理,使用Vue实现proxy代理的注意事项有哪些,下面就是实战案例,一起来看一下。 // config/index.js 文件proxyTable: { ‘/api’: { target: ‘ht…

    编程技术 2025年3月8日
    200
  • 利用Angular如何实现变化检测

    这篇文章主要介绍了浅谈angular 的变化检测的方法,现在分享给大家,也给大家做个参考。 Change Detection (变化检测) 是 Angular 2 中最重要的一个特性。当组件中的数据发生变化的时候,Angular 2 能检测…

    编程技术 2025年3月8日
    200
  • 怎样使用Vue实现倒计时按钮

    这次给大家带来怎样使用Vue实现倒计时按钮,使用Vue实现倒计时按钮的注意事项有哪些,下面就是实战案例,一起来看一下。 在项目开发里,我们经常会遇到发送验证码、点击了之后有60秒倒计时的按钮,很常见却也很简单,但是在写这个按钮的时候有个别地…

    2025年3月8日 编程技术
    200
  • 利用JS脚本加载后如何实现能执行相应回调函数

    本文主要讲解怎么在成功加载 js 文件后再执行相应回调任务,对js脚本加载后执行相应回调函数的操作方法感兴趣的朋友,通过本文学习下吧 项目中经常会遇到这样的问题:当某个 js 脚本加载完成后再执行相应任务,但很多朋友可能并不知道怎么判断我们…

    编程技术 2025年3月8日
    200
  • 通过webpack项目如何实现调试以及独立打包配置文件(详细教程)

    下面我就为大家分享一篇webpack项目调试以及独立打包配置文件的方法,具有很好的参考价值,希望对大家有所帮助。 webpack项目调试 -sourcemap webpack配置提供了devtool这个选项,如果设置为 ‘#source-m…

    编程技术 2025年3月8日
    200
  • 如何使用react redux

    这次给大家带来如何使用react redux,使用react redux的注意事项有哪些,下面就是实战案例,一起来看一下。 环境准备 为了方便,这里使用create-react-app搭建react环境 create-react-app m…

    编程技术 2025年3月8日
    200
  • 怎样操作vue实现通过手机发送短信验证码

    这次给大家带来怎样操作vue实现通过手机发送短信验证码,操作vue实现通过手机发送短信验证码的注意事项有哪些,下面就是实战案例,一起来看一下。 效果如下: 代码如下: template代码: 手机注册 获取验证码 {{auth_time}}…

    2025年3月8日
    200
  • 通过vue-cli+webpack项目如何实现修改项目名称

    下面我就为大家分享一篇vue-cli+webpack项目 修改项目名称的方法,具有很好的参考价值,希望对大家有所帮助。 使用vue-cli+webpack创建的项目,修改文件名称或者更改文件的位置,运营时会报错,是因为npm项目,在安装依赖…

    编程技术 2025年3月8日
    200

发表回复

登录后才能评论