react native 的上拉加载一直困扰着自己,一直用的第三方组件,但是可维护性不高,而且也不太好用,最近工作没那么忙,就研究下了官方的FlatList,做出来的成果,比第三方组件流畅度高好多,而且也很好用

官方介绍:https://reactnative.cn/docs/flatlist/

下面是效果图:

ios效果图

android效果图

总体思路就是:就是计算屏幕高度,然后减去导航的头部,根据列表高度计算出每页的个数,然后向上取整。这样做的目的是:防止不满屏状态下的,onEndReached函数的主动触发。

方法实现:

 //满屏页面判断
 fullScreenJusting(ItemHeight) {
  const screnHeight = screnInfo.size.height;   //屏幕高度
  //计算列表个数
  const listNum = (screnHeight - 40) / ItemHeight;
  return Math.ceil(listNum);
 }

下拉刷新用的是 RefreshControl

官网地址:https://reactnative.cn/docs/refreshcontrol/#progressbackgroundcolor

具体代码:

import React, { Component } from 'react';
import {
 View,
 Text,
 Image,
 StyleSheet,
 FlatList,
 RefreshControl,
 ActivityIndicator,
} from 'react-native';
import { SafeAreaView } from 'react-navigation';
import screnInfo from '../utils/View';
import BaseStyle from '../constants/Style';
import { QUESTION_LIST } from '../constants/Api';
import { form_req } from '../utils/Request';

export default class TestScreen extends Component {
 constructor(props) {
  super(props);
  this.state = {
   data: [
   ],
   refreshing: false,
   fresh: true,
   animating: true,
   nomore: false,
   pageSize: 0,
   pageNumber: 1,
  };
 }
 componentDidMount() { //初始化的时候要判断长度 控制上拉加载

  const ListNums = this.fullScreenJusting(50);
  this.setState({
   pageSize: ListNums
  })
  this.onEndReachedCalled = false;
   this.getOrderList(ListNums, 1, true);

 }
 //满屏页面判断
 fullScreenJusting(ItemHeight) {
  const screnHeight = screnInfo.size.height;   //屏幕高度
  //计算列表个数
  const listNum = (screnHeight - 40) / ItemHeight;
  return Math.ceil(listNum);
 }

 getOrderList(ListNums, pageNumber, fresh) {
  let nomore;
  form_req(QUESTION_LIST, {
   page: pageNumber,
   perpage: ListNums,
  }).then(res => {
   if (res.code == 200) {
    const item = res.data;
    if (item.length < ListNums) {
     nomore = true
    } else {
     nomore = false
    }
    if (fresh) {
     this.setState({
      data: item,
      nomore: nomore
     })
     
    } else {
     this.setState({
      data: this.state.data.concat(item),
      nomore: nomore,
     })
    }
    // this.onEndReachedCalledDuringMomentum = true;

   } else {

   }
  });
 }

 renderItem = item => {
  return (
   <View style={styles.item} key={item.id}>
    <Text>{item.name}</Text>
   </View>
  );
 };
 //列表线
 ItemSeparatorComponent = () => {
  return <View style={styles.baseLine} />;
 };
 //头部
 ListHeaderComponent = () => { };
 //尾部
 ListFooterComponent = () => {
  return (
   <View style={styles.bottomfoot}>
    {
     this.state.data.length != 0 ?
      this.state.nomore ? (
       <Text style={styles.footText}>- 我是有底线的 -</Text>
      ) : (
        <View style={styles.activeLoad}>
         <ActivityIndicator size="small" animating={this.state.animating} />
         <Text style={[styles.footText, styles.ml]}>加载更多...</Text>
        </View>
       )
      :
      null
    }

   </View>
  );
 };
 //为空时
 ListEmptyComponent() {
  return (
   <View style={styles.noListView}>
    {/* <Image
     style={styles.noListImage}
     source={require('../images/status/order_no_record.png')}
    /> */}
    <Text style={styles.NoListText}>暂无订单</Text>
   </View>
  );
 }
 _keyExtractor = (item,index) => item.id;

 _onEndReached = () => {
  if (!this.state.nomore && this.onEndReachedCalled ) {
   this.getOrderList(this.state.pageSize,   this.state.pageNumber, false);
  }
  this.onEndReachedCalled=true;

 };
 _onRefresh() {
  this.setState({ nomore: false, pageNumber: 1 }, () => {
   this.getOrderList(this.state.pageSize, 1, true);
  })

 }

 render() {
  return (
   <SafeAreaView style={BaseStyle.flex}>
    <View style={styles.listConten}>
     <FlatList
      data={this.state.data}
      keyExtractor={this._keyExtractor}
      onEndReached={this._onEndReached}
      refreshing={true}
      renderItem={({ item }) => this.renderItem(item)}
      ItemSeparatorComponent={this.ItemSeparatorComponent}
      ListEmptyComponent={this.ListEmptyComponent}
      ListFooterComponent={this.ListFooterComponent}
      onEndReachedThreshold={0.1}
      refreshControl={
       <RefreshControl
        refreshing={this.state.refreshing}
        colors={['#ff0000', '#00ff00', '#0000ff']}
        progressBackgroundColor={"#ffffff"}
        onRefresh={() => {
         this._onRefresh();
        }}
       />
      }
     />
    </View>
   </SafeAreaView>
  );
 }
}

const styles = StyleSheet.create({
 listConten: {
  flex: 1,
  backgroundColor: '#ffffff',
 },
 item: {
  flexDirection: 'row',
  justifyContent: 'center',
  alignItems: "center",
  backgroundColor: '#ffffff',
  height: 50,
 },
 baseLine: {
  width: screnInfo.size.width,
  height: 1,
  backgroundColor: '#eeeeee',
 },
 noListView: {
  width: screnInfo.size.width,
  height: screnInfo.size.height - 140,
  justifyContent: 'center',
  alignItems: 'center',
 },
 NoListText: {
  marginTop: 15,
  fontSize: 18,
  color: '#999999',
 },
 noListImage: {
  width: 130,
  height: 140,
 },
 bottomfoot: {
  flexDirection: 'row',
  justifyContent: 'center',
  alignItems: 'center',
  padding: 10,
 },
 footText: {
  marginTop: 5,
  fontSize: 12,
  color: '#999999',
 },

 activeLoad: {
  flexDirection: 'row',
  justifyContent: 'center',
  alignItems: 'center',
 },
 ml: {
  marginLeft: 10,
 },
});

这里的坑就是:当初始化进来页面的时候 上拉会主动触发,所以这里加了一个开关 this.onEndReachedCalled = false; 初始化给一个false 当触发了 设为true,放在调取接口之后

代码都很简单易懂~ 有什么不懂的,或者有什么问题请留言,希望对大家的学习有所帮助,也希望大家多多支持Devmax。

react native基于FlatList下拉刷新上拉加载实现代码示例的更多相关文章

  1. 原生js仿写手机端下拉刷新

    这篇文章主要为大家详细介绍了原生js仿写手机端下拉刷新,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  2. iOS表视图之下拉刷新控件功能的实现方法

    下拉刷新是重新刷新表视图或列表,以便重新加载数据,这种模式广泛用于移动平台,相信大家对于此也是非常熟悉的,那么iOS是如何做到的下拉刷新呢?下面小编给大家分享iOS表视图之下拉刷新控件的实现方法,一起看看吧

  3. AnglarJs中的上拉加载实现代码

    上拉加载,是目前手机网站加载数据的一种常用方式,本文主要讲解AnglarJs集成,上拉加载功能。感兴趣的朋友跟随脚本之家小编一起学习吧

  4. React Native学习教程之自定义NavigationBar详解

    这篇文章主要给大家介绍了关于React Native学习教程之自定义NavigationBar的相关资料,文中通过是示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。

  5. ios基于MJRefresh实现上拉刷新和下拉加载动画效果

    本篇文章主要介绍了ios基于MJRefresh实现上拉刷新和下拉加载动画效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  6. react native基于FlatList下拉刷新上拉加载实现代码示例

    这篇文章主要介绍了react native基于FlatList下拉刷新上拉加载实现代码示例

  7. React-Native实现ListView组件之上拉刷新实例(iOS和Android通用)

    本篇文章主要介绍了React-Native实现ListView组件之上拉刷新实例(iOS和Android通用),具有一定的参考价值,有兴趣的可以了解一下

  8. ReactNative实现图片上传功能的示例代码

    本篇文章主要介绍了ReactNative实现图片上传功能的示例代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。

  9. iOS实现MJRefresh下拉刷新(上拉加载)使用详解

    本篇文章主要介绍了iOS实现MJRefresh下拉刷新(上拉加载)使用详解,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。

  10. ReactNative踩坑之配置调试端口的解决方法

    本篇文章主要介绍了ReactNative踩坑之配置调试端口的解决方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

随机推荐

  1. js中‘!.’是什么意思

  2. Vue如何指定不编译的文件夹和favicon.ico

    这篇文章主要介绍了Vue如何指定不编译的文件夹和favicon.ico,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  3. 基于JavaScript编写一个图片转PDF转换器

    本文为大家介绍了一个简单的 JavaScript 项目,可以将图片转换为 PDF 文件。你可以从本地选择任何一张图片,只需点击一下即可将其转换为 PDF 文件,感兴趣的可以动手尝试一下

  4. jquery点赞功能实现代码 点个赞吧!

    点赞功能很多地方都会出现,如何实现爱心点赞功能,这篇文章主要为大家详细介绍了jquery点赞功能实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  5. AngularJs上传前预览图片的实例代码

    使用AngularJs进行开发,在项目中,经常会遇到上传图片后,需在一旁预览图片内容,怎么实现这样的功能呢?今天小编给大家分享AugularJs上传前预览图片的实现代码,需要的朋友参考下吧

  6. JavaScript面向对象编程入门教程

    这篇文章主要介绍了JavaScript面向对象编程的相关概念,例如类、对象、属性、方法等面向对象的术语,并以实例讲解各种术语的使用,非常好的一篇面向对象入门教程,其它语言也可以参考哦

  7. jQuery中的通配符选择器使用总结

    通配符在控制input标签时相当好用,这里简单进行了jQuery中的通配符选择器使用总结,需要的朋友可以参考下

  8. javascript 动态调整图片尺寸实现代码

    在自己的网站上更新文章时一个比较常见的问题是:文章插图太宽,使整个网页都变形了。如果对每个插图都先进行缩放再插入的话,太麻烦了。

  9. jquery ajaxfileupload异步上传插件

    这篇文章主要为大家详细介绍了jquery ajaxfileupload异步上传插件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. React学习之受控组件与数据共享实例分析

    这篇文章主要介绍了React学习之受控组件与数据共享,结合实例形式分析了React受控组件与组件间数据共享相关原理与使用技巧,需要的朋友可以参考下

返回
顶部