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 相关文章推荐
javascript 框架小结 个人工作经验
Jun 13 Javascript
js修改table中Td的值(定义td的双击事件)
Jan 10 Javascript
jQuery中animate()方法用法实例
Dec 24 Javascript
了解Javascript的模块化开发
Mar 02 Javascript
js+canvas绘制矩形的方法
Jan 28 Javascript
深入理解JavaScript内置函数
Jun 03 Javascript
js enter键激发事件实例代码
Aug 17 Javascript
vue中子组件向父组件传递数据的实例代码(实现加减功能)
Apr 20 Javascript
纯JS实现的读取excel文件内容功能示例【支持所有浏览器】
Jun 23 Javascript
vue项目中使用Svg的方法
Oct 24 Javascript
CountUp.js实现数字滚动增值效果
Oct 17 Javascript
js回调函数原理与用法案例分析
Mar 04 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发送post请求的三种方法
2014/02/11 PHP
php 判断字符串中是否包含html标签
2014/02/17 PHP
php使用ftp实现文件上传与下载功能
2017/07/21 PHP
用js判断浏览器是否是IE的比较好的办法
2007/05/08 Javascript
js下用层来实现select的title提示属性
2010/02/23 Javascript
js怎么判断flash swf文件是否加载完毕
2014/08/14 Javascript
JavaScript实现判断图片是否加载完成的3种方法整理
2015/03/13 Javascript
详解JavaScript中Date.UTC()方法的使用
2015/06/12 Javascript
JavaScript Array对象详解
2016/03/01 Javascript
JavaScript继承学习笔记【新手必看】
2016/05/10 Javascript
jQuery中使用animate自定义动画的方法
2016/05/29 Javascript
jquery判断页面网址是否有效的两种方法
2016/12/11 Javascript
JS实现的按钮点击颜色切换功能示例
2017/10/19 Javascript
在vue中使用SockJS实现webSocket通信的过程
2018/08/29 Javascript
javascript面向对象三大特征之多态实例详解
2019/07/24 Javascript
vue element 生成无线级左侧菜单的实现代码
2019/08/21 Javascript
vue导航栏部分的动态渲染实例
2019/11/01 Javascript
JS如何生成随机验证码
2020/03/02 Javascript
详解vite+ts快速搭建vue3项目以及介绍相关特性
2021/02/25 Vue.js
[01:10]DOTA2次级职业联赛 - Fly战队宣传片
2014/12/01 DOTA
Python3 入门教程 简单但比较不错
2009/11/29 Python
Python实现的石头剪子布代码分享
2014/08/22 Python
实例讲解Python的函数闭包使用中应注意的问题
2016/06/20 Python
Python基础中所出现的异常报错总结
2016/11/19 Python
Python断言assert的用法代码解析
2018/02/03 Python
Django choices下拉列表绑定实例
2020/03/13 Python
Python pip安装模块提示错误解决方案
2020/05/22 Python
Python测试框架:pytest学习笔记
2020/10/20 Python
完美解决Pycharm中matplotlib画图中文乱码问题
2021/01/11 Python
django inspectdb 操作已有数据库数据的使用步骤
2021/02/07 Python
写给妈妈的道歉信
2014/01/11 职场文书
餐饮总经理岗位职责
2014/03/07 职场文书
工伤赔偿协议书范本
2014/04/15 职场文书
关爱留守儿童标语
2014/06/18 职场文书
2016年春节慰问信息大全
2015/11/30 职场文书
sql查询结果列拼接成逗号分隔的字符串方法
2021/05/25 SQL Server