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 相关文章推荐
js每次Title显示不同的名言
Sep 25 Javascript
js中浮点型运算BUG的解决方法说明
Jan 06 Javascript
详谈jQuery中的this和$(this)
Nov 13 Javascript
使用Node.js配合Nginx实现高负载网络
Jun 28 Javascript
纯js模拟div层弹性运动的方法
Jul 27 Javascript
js如何实现点击标签文字,文字在文本框出现
Aug 05 Javascript
使用JavaScript脚本无法直接改变Asp.net中Checkbox控件的Enable属性的解决方法
Sep 16 Javascript
Easyui ueditor 整合解决不能编辑的问题(推荐)
Jun 25 Javascript
JavaScript编程设计模式之构造器模式实例分析
Oct 25 Javascript
vue裁切预览组件功能的实现步骤
May 04 Javascript
Vue验证码60秒倒计时功能简单实例代码
Jun 22 Javascript
jQuery AJAX与jQuery事件的分析讲解
Feb 18 jQuery
关于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
NO3第三帝国留言簿制作过程
2006/10/09 PHP
实用PHP会员权限控制实现原理分析
2011/05/29 PHP
php中fgetcsv()函数用法实例
2014/11/28 PHP
php获取本周开始日期和结束日期的方法
2015/03/09 PHP
PHP实现二维数组去重功能示例
2017/01/12 PHP
php自定义函数br2nl实现将html中br换行符转换为文本输入中换行符的方法【与函数nl2br功能相反】
2017/02/17 PHP
CentOS7.0下安装PHP5.6.30服务的教程详解
2018/09/29 PHP
实例说明js脚本语言和php脚本语言的区别
2019/04/04 PHP
jQuery结合Json提交数据到Webservice,并接收从Webservice返回的Json数据
2011/02/18 Javascript
Google的跟踪代码 动态加载js代码方法应用
2012/11/12 Javascript
JS小功能(button选择颜色)简单实例
2013/11/29 Javascript
浅析javascript的return语句
2015/12/15 Javascript
jQuery.form.js插件不能解决连接超时(timeout)的原因分析及解决方法
2016/10/14 Javascript
bootstrap监听滚动实现头部跟随滚动
2016/11/08 Javascript
基于Angular.js实现的触摸滑动动画实例代码
2017/02/19 Javascript
详解用node搭建简单的静态资源管理器
2017/08/09 Javascript
Nodejs把接收图片base64格式保存为文件存储到服务器上
2018/09/26 NodeJs
ES6 Object属性新的写法实例小结
2019/06/25 Javascript
Vue 使用beforeEach实现登录状态检查功能
2019/10/31 Javascript
React中使用UMEditor的方法示例
2019/12/27 Javascript
Vue 实现对quill-editor组件中的工具栏添加title
2020/08/03 Javascript
JavaScript检测是否开启了控制台(F12调试工具)
2020/10/02 Javascript
[00:32]2018DOTA2亚洲邀请赛Secret出场
2018/04/03 DOTA
列举Python中吸引人的一些特性
2015/04/09 Python
python实现线程池的方法
2015/06/30 Python
Python实现堆排序的方法详解
2016/05/03 Python
Python字符串处理实现单词反转
2017/06/14 Python
Python下opencv图像阈值处理的使用笔记
2019/08/04 Python
Nobody Denim官网:购买高级女士牛仔裤
2021/03/15 全球购物
优秀毕业自我鉴定
2014/02/15 职场文书
电焊工岗位职责
2014/03/06 职场文书
付款委托书范本
2014/10/05 职场文书
2015年市场部工作总结
2015/04/30 职场文书
预备党员入党感想
2015/08/10 职场文书
广告策划的实习心得体会总结!
2019/07/22 职场文书
Python中字符串对象语法分享
2022/02/24 Python