欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-07-04 17:38:33
react native 的上拉加载一直困扰着自己,一直用的第三方组件,但是可维护性不高,而且也不太好用,最近工作没那么忙,就研究下了官方的flatlist,做出来的成果,...

react native 的上拉加载一直困扰着自己,一直用的第三方组件,但是可维护性不高,而且也不太好用,最近工作没那么忙,就研究下了官方的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

官网地址:

具体代码:

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下拉刷新上拉加载实现代码示例

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