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


Posted in Javascript onSeptember 30, 2018

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

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

下面是效果图:

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

ios效果图

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

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,放在调取接口之后

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

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

Javascript 相关文章推荐
jquery 结合C#后台的数组对文章的关键字自动添加链接的代码
Jul 15 Javascript
jQuery操作CheckBox的方法介绍(选中,取消,取值)
Feb 04 Javascript
借助JavaScript脚本判断浏览器Flash Player信息的方法
Jul 09 Javascript
JQuery中模拟image的ajaxPrefilter与ajaxTransport处理
Jun 19 Javascript
再JavaScript的jQuery库中编写动画效果的指南
Aug 13 Javascript
学习JavaScript设计模式之单例模式
Jan 19 Javascript
如何使用Bootstrap的modal组件自定义alert,confirm和modal对话框
Mar 01 Javascript
移动端使用localStorage缓存Js和css文的方法(web开发)
Sep 20 Javascript
Mac下安装vue
Apr 11 Javascript
JavaScript实现一个带AI的井字棋游戏源码
May 21 Javascript
vue component 中引入less文件报错 Module build failed
Apr 17 Javascript
JavaScript中document.activeELement焦点元素介绍
Nov 27 Javascript
关于AngularJS中ng-repeat不更新视图的解决方法
Sep 30 #Javascript
angular5 子组件监听父组件传入值的变化方法
Sep 30 #Javascript
小程序视频或音频自定义可拖拽进度条的示例代码
Sep 30 #Javascript
angularjs1.5 组件内用函数向外传值的实例
Sep 30 #Javascript
angular2 组件之间通过service互相传递的实例
Sep 30 #Javascript
详解如何webpack使用DllPlugin
Sep 30 #Javascript
浅谈angular2子组件的事件传递(任意组件事件传递)
Sep 30 #Javascript
You might like
PHP中的函数嵌套层数限制分析
2011/06/13 PHP
PHP 代码规范小结
2012/03/08 PHP
浅谈使用 PHP 进行手机 APP 开发(API 接口开发)
2014/08/11 PHP
Yii获取当前url和域名的方法
2015/06/08 PHP
全面解析PHP操作Memcache基本函数
2016/07/14 PHP
ExtJS的FieldSet的column列布局
2009/11/20 Javascript
Aptana调试javascript图解教程
2009/11/30 Javascript
用jQuery获取IE9下拉框默认值问题探讨
2013/07/22 Javascript
jquery中get,post和ajax方法的使用小结
2014/02/04 Javascript
jQuery应用之jQuery链用法实例
2015/01/19 Javascript
AngularJS 2.0入门权威指南
2016/10/08 Javascript
微信小程序实现点击返回顶层的方法
2017/07/12 Javascript
JavaScript数据结构与算法之队列原理与用法实例详解
2017/11/22 Javascript
讲解vue-router之命名路由和命名视图
2018/05/28 Javascript
基于游标的分页接口实现代码示例
2018/11/12 Javascript
JS中this的4种绑定规则详解
2020/02/04 Javascript
在vue中axios设置timeout超时的操作
2020/09/04 Javascript
Python性能提升之延迟初始化
2016/12/04 Python
Python3实现发送QQ邮件功能(附件)
2020/12/23 Python
Django用户登录与注册系统的实现示例
2020/06/03 Python
Python HTMLTestRunner如何下载生成报告
2020/09/04 Python
BeautifulSoup获取指定class样式的div的实现
2020/12/07 Python
python实现简单的学生管理系统
2021/02/22 Python
python反编译教程之2048小游戏实例
2021/03/03 Python
艺术用品:Arteza
2018/11/25 全球购物
JSF面试题:Jsf中的核心类用那些?有什么作用?LiftCycle六大生命周期是什么?
2014/07/17 面试题
毕业生个人求职的自我评价
2013/10/28 职场文书
2014自主招生自荐信策略
2014/01/27 职场文书
国际经济与贸易专业大学生职业规划书
2014/03/01 职场文书
2014年秋季开学寄语
2014/08/02 职场文书
公务员政审材料
2014/12/23 职场文书
2015年社区工作总结
2015/04/08 职场文书
军训后的感想
2015/08/07 职场文书
JPA如何使用entityManager执行SQL并指定返回类型
2021/06/15 Java/Android
nginx之queue的具体使用
2022/06/28 Servers
Win11控制面板快捷键是什么?Win11打开控制面板的方法汇总
2022/07/07 数码科技