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学习笔记(十)
Jan 17 Javascript
javascript函数中的arguments参数
Aug 01 Javascript
jquery获取特定name所有选中的checkbox,支持IE9标准模式
Mar 18 Javascript
JS实现点击复选框将按钮或文本框变为灰色不可用的方法
Aug 11 Javascript
javascript中利用柯里化函数实现bind方法【推荐】
Apr 29 Javascript
jQuery实现最简单实用的分秒倒计时
Feb 05 Javascript
重新理解JavaScript的六种继承方式
Mar 24 Javascript
Bootstrap Table使用整理(五)之分页组合查询
Jun 09 Javascript
jquery.param()实现数组或对象的序列化方法
Oct 08 jQuery
js如何实现元素曝光上报
Aug 07 Javascript
layer弹出层取消遮罩的方法
Sep 25 Javascript
package.json中homepage属性的作用详解
Mar 11 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
《雄兵连》系列首部大电影《烈阳天道》:可能是因为期望值太高了
2020/08/18 国漫
探讨PHP使用eAccelerator的API开发详解
2013/06/09 PHP
php实现微信公众平台账号自定义菜单类
2014/12/02 PHP
js 数组的for循环到底应该怎么写?
2010/05/31 Javascript
jQuery仿Excel表格编辑功能的实现代码
2013/05/01 Javascript
js设置cookie过期及清除浏览器对应名称的cookie
2013/10/24 Javascript
JavaScript中检查对象property的存在性方法介绍
2014/12/30 Javascript
JQuery实现的图文自动轮播效果插件
2015/06/19 Javascript
简单介绍JavaScript中字符串创建的基本方法
2015/07/07 Javascript
js根据手机客户端浏览器类型,判断跳转官网/手机网站多个实例代码
2016/04/30 Javascript
Jquery组件easyUi实现选项卡切换示例
2016/08/23 Javascript
Javascript 实现计算器时间功能详解及实例(二)
2017/01/08 Javascript
javascript数组定义的几种方法
2017/10/06 Javascript
js 获取json数组里面数组的长度实例
2017/10/31 Javascript
bootstrap 弹出框modal添加垂直方向滚轴效果
2018/07/09 Javascript
vue实现重置表单信息为空的方法
2018/09/29 Javascript
一文了解Vue中的nextTick
2019/05/06 Javascript
vue h5移动端禁止缩放代码
2019/10/28 Javascript
详解微信小程序动画Animation执行过程
2020/09/23 Javascript
vue实现简易的双向数据绑定
2020/12/29 Vue.js
用python代码做configure文件
2014/07/20 Python
Python中的MongoDB基本操作:连接、查询实例
2015/02/13 Python
详解django中使用定时任务的方法
2018/09/27 Python
如何安装并使用conda指令管理python环境
2019/07/10 Python
Django中使用MySQL5.5的教程
2019/12/18 Python
使用HTML5里的classList操作CSS类
2016/06/28 HTML / CSS
为什么UNION ALL比UNION快
2016/03/17 面试题
大学学习生活感言
2014/01/18 职场文书
黄河的主人教学反思
2014/02/07 职场文书
销售业务员岗位职责
2015/02/13 职场文书
2015大学生求职信范文
2015/03/20 职场文书
社区志愿者服务心得体会
2016/01/22 职场文书
导游词之西江千户苗寨
2019/12/24 职场文书
Python读取文件夹下的所有文件实例代码
2021/04/02 Python
Python中常见的导入方式总结
2021/05/06 Python
Go中的条件语句Switch示例详解
2021/08/23 Golang