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中的this绑定介绍
Sep 22 Javascript
jQuery aminate方法定位到页面具体位置
Dec 26 Javascript
js使用循环清空某个div中的input标签值
Sep 29 Javascript
使用JavaScript制作一个简单的计数器的方法
Jul 07 Javascript
swtich/if...else的替代语句
Aug 16 Javascript
JS+CSS实现仿支付宝菜单选中效果代码
Sep 25 Javascript
JavaScript实现同时调用多个函数的方法
Nov 09 Javascript
JavaScript trim 实现去除字符串首尾指定字符的简单方法
Dec 27 Javascript
layui分页效果实现代码
May 19 Javascript
React学习笔记之事件处理(二)
Jul 02 Javascript
jQuery实现checkbox全选、反选及删除等操作的方法详解
Aug 02 jQuery
javascript 高级语法之继承的基本使用方法示例
Nov 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
mysql 搜索之简单应用
2007/04/27 PHP
PHP gbk环境下json_dencode传送来的汉字
2012/11/13 PHP
PHP英文字母大小写转换函数小结
2014/05/03 PHP
国产PHP开发框架myqee新手快速入门教程
2014/07/14 PHP
laravel框架学习笔记之组件化开发实现方法
2020/02/01 PHP
php使用fputcsv实现大数据的导出操作详解
2020/02/27 PHP
javascript getElementsByClassName函数
2010/04/01 Javascript
Jquery中删除元素的实现代码
2011/12/29 Javascript
poshytip 基于jquery的 插件 主要用于显示微博人的图像和鼠标提示等
2012/10/12 Javascript
Jquery和JS用外部变量获取Ajax返回的参数值的方法实例(超简单)
2013/06/17 Javascript
js保留两位小数使用toFixed实现
2013/07/29 Javascript
jquery动态改变onclick属性导致失效的问题解决方法
2013/12/04 Javascript
javascript实现捕捉键盘上按下的键
2015/05/05 Javascript
JavaScript是如何实现继承的(六种方式)
2016/03/31 Javascript
用js读写cookie的简单方法(推荐)
2016/08/08 Javascript
nodeJs内存泄漏问题详解
2016/09/05 NodeJs
使用React实现轮播效果组件示例代码
2016/09/05 Javascript
knockoutjs模板实现树形结构列表
2017/07/31 Javascript
详解Vue中使用Echarts的两种方式
2018/07/03 Javascript
Element输入框带历史查询记录的实现示例
2019/01/15 Javascript
13 个npm 快速开发技巧(推荐)
2019/07/04 Javascript
js实现点击生成随机div
2020/01/16 Javascript
全局安装 Vue cli3 和 继续使用 Vue-cli2.x操作
2020/09/08 Javascript
如何使用JS console.log()技巧提高工作效率
2020/10/14 Javascript
VUE和Antv G6实现在线拓扑图编辑操作
2020/10/28 Javascript
[49:08]OpTic vs Serenity 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
Python开发实例分享bt种子爬虫程序和种子解析
2014/05/21 Python
python实现二分查找算法
2017/09/21 Python
基于python使用tibco ems代码实例
2019/12/20 Python
为什么称python为胶水语言
2020/06/16 Python
keras 模型参数,模型保存,中间结果输出操作
2020/07/06 Python
绩效考核实施方案
2014/03/18 职场文书
消防宣传口号
2014/06/16 职场文书
2015年暑假工作总结
2015/07/13 职场文书
Oracle 多表查询基本语法实例
2022/04/18 Oracle
GTX1660显卡搭配显示器推荐
2022/04/19 数码科技