1.下拉刷新/上拉加载更多 组件(RefreshListView)

src/components/RefreshListView/index.js

/**
* 下拉刷新/上拉加载更多 组件(RefreshListView)
*/
import React, {PureComponent} from 'react';
import PropTypes from 'prop-types';
import {
View,
Text,
StyleSheet,
FlatList,
ActivityIndicator,
TouchableOpacity,
ViewPropTypes,
RefreshControl
} from 'react-native' const RefreshState = {
Idle: 0,
HeaderRefreshing: 1,
FooterRefreshing: 2,
NoMoreData: 3,
Failure: 4,
EmptyData: 5,
} class RefreshListView extends PureComponent {
static propTypes = {
data: PropTypes.array.isRequired,
renderItem: PropTypes.func.isRequired,
refreshState: PropTypes.number.isRequired, listRef: PropTypes.node,
onHeaderRefresh: PropTypes.func,
footerContainerStyle: ViewPropTypes.style,
footerTextStyle: ViewPropTypes.style, disabledSeparator: PropTypes.bool,
disabledHeaderRefresh: PropTypes.bool,
footerRefreshingText: PropTypes.string,
footerFailureText: PropTypes.string,
footerNoMoreDataText: PropTypes.string,
footerEmptyDataText: PropTypes.string, ListEmptyComponent: PropTypes.node,
footerRefreshingComponent: PropTypes.node,
footerFailureComponent: PropTypes.node,
footerNoMoreDataComponent: PropTypes.node,
footerEmptyDataComponent: PropTypes.node,
} static defaultProps = {
disabledHeaderRefresh: false,
footerRefreshingText: '数据加载中…',
footerFailureText: '点击重新加载',
footerNoMoreDataText: '已加载全部数据',
footerEmptyDataText: '暂时没有相关数据',
} componentWillReceiveProps(nextProps) {} componentDidUpdate(prevProps, prevState) {} onHeaderRefresh = () => {
if (this.shouldStartHeaderRefreshing()) {
this.props.onHeaderRefresh(RefreshState.HeaderRefreshing)
}
} onEndReached = () => {
if (this.shouldStartFooterRefreshing()) {
this.props.onFooterRefresh && this.props.onFooterRefresh(RefreshState.FooterRefreshing)
}
} shouldStartHeaderRefreshing = () => {
if (this.props.refreshState == RefreshState.HeaderRefreshing || this.props.refreshState == RefreshState.FooterRefreshing) {
return false
}
return true
} shouldStartFooterRefreshing = () => {
const {refreshState, data} = this.props
if (data.length == 0) {
return false
}
return (refreshState == RefreshState.Idle)
} renderSeparator = () => (
<View style={{height: 1, backgroundColor: '#e0e0e0'}} />
) renderFooter = () => {
let footer = null let {
footerRefreshingText,
footerFailureText,
footerNoMoreDataText,
footerEmptyDataText, footerRefreshingComponent,
footerFailureComponent,
footerNoMoreDataComponent,
footerEmptyDataComponent,
} = this.props switch (this.props.refreshState) {
case RefreshState.Idle: {
footer = (<View style={styles.footerContainer} />)
break
}
case RefreshState.Failure: {
footer = (
<TouchableOpacity onPress={() => {
if (this.props.data.length == 0) {
this.props.onHeaderRefresh && this.props.onHeaderRefresh(RefreshState.HeaderRefreshing)
} else {
this.props.onFooterRefresh && this.props.onFooterRefresh(RefreshState.FooterRefreshing)
}
}}
>
{footerFailureComponent ? footerFailureComponent : (
<View style={styles.footerContainer}>
<Text style={styles.footerText}>{footerFailureText}</Text>
</View>
)}
</TouchableOpacity>
)
break
}
case RefreshState.EmptyData: {
footer = (
<TouchableOpacity onPress={() => {
this.props.onHeaderRefresh && this.props.onHeaderRefresh(RefreshState.HeaderRefreshing)
}}
>
{footerEmptyDataComponent ? footerEmptyDataComponent : (
<View style={styles.footerContainer}>
<Text style={styles.footerText}>{footerEmptyDataText}</Text>
</View>
)}
</TouchableOpacity>
)
break
}
case RefreshState.FooterRefreshing: {
footer = footerRefreshingComponent ? footerRefreshingComponent : (
<View style={styles.footerContainer} >
<ActivityIndicator size="small" color="#888888" />
<Text style={[styles.footerText, {marginLeft: 7}]}>{footerRefreshingText}</Text>
</View>
)
break
}
case RefreshState.NoMoreData: {
footer = footerNoMoreDataComponent ? footerNoMoreDataComponent : (
<View style={styles.footerContainer} >
<Text style={styles.footerText}>{footerNoMoreDataText}</Text>
</View>
)
break
}
}
return footer
} render() {
const {renderItem, ...rest} = this.props
return (
<FlatList
ref={this.props.listRef}
{...rest}
// 行与行之间的分隔线组件
ItemSeparatorComponent={this.props.disabledSeparator?false:this.renderSeparator}
// 列表为空时渲染该组件
ListEmptyComponent={this.props.ListEmptyComponent}
// 头部组件
ListHeaderComponent={this.props.renderHeader}
// 尾部组件
ListFooterComponent={this.renderFooter}
// 当列表被滚动到距离内容最底部不足onEndReachedThreshold的距离时调用
onEndReached={this.onEndReached}
// 刷新组件
refreshControl={
this.props.disabledHeaderRefresh?false:<RefreshControl
colors={['#00ff00',"#9Bd35A", "#689F38",]}
refreshing={this.props.refreshState == RefreshState.HeaderRefreshing}
onRefresh={this.onHeaderRefresh}
/>}
// 决定当距离内容最底部还有多远时触发onEndReached回调
onEndReachedThreshold={0.1}
// 根据行数据data,渲染每一行的组件
renderItem={renderItem}
/>
)
}
} const styles = StyleSheet.create({
footerContainer: {
flex: 1,
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
padding: 10,
height: 44,
},
footerText: {
fontSize: 14,
color: '#555555',
},
}) export {
RefreshState,
} export default RefreshListView;

2.页面调用

(1)定义全局变量

// 刷新状态
global.RefreshState = {
Idle: 0, // 加载成功
HeaderRefreshing: 1, // 开始下拉刷新
FooterRefreshing: 2, // 开始上拉翻页
NoMoreData: 3, // 加载全部数据
Failure: 4, // 加载失败
EmptyData: 5, // 服务器没有数据
}

(2)通用store

@observable
refreshState: any; /**
* 改变refreshState的值
* @param refreshState
*/
@action setRefreshState(refreshState) {
this.refreshState = refreshState
}

(3)当前 store

// 加载成功
this.setRefreshState(RefreshState.Idle); if(!res.data.topics.length){
// 服务器没有数据
this.setRefreshState(RefreshState.EmptyData);
}

(4)页面

const { data, refreshState, loadData, loadMoreData } = this.store;

// 新闻列表
store = new NewsStore(); // 子组件渲染
_renderRow(obj) {
let item = obj.item;
return (
<ListRow
key={item.id}
title={item.title}
onPress={() => {
// 跳转详情页
Actions.homeDetailPage({detail: item})
}}
/>
)
} <RefreshListView
data={toJS(data)}
keyExtractor={(item,index) => index.toString()}
renderItem={this._renderRow.bind(this)} refreshState={refreshState}
onHeaderRefresh={loadData.bind(this.store)}
onFooterRefresh={loadMoreData.bind(this.store)}
/>

3.效果图

react-native 模仿原生 实现下拉刷新/上拉加载更多(RefreshListView)的更多相关文章

  1. SwipeRefreshLayout实现下拉刷新上滑加载

    1. 效果图 2.RefreshLayout.java package myapplication.com.myapplication; import android.content.Context; ...

  2. Android 下拉刷新上啦加载SmartRefreshLayout + RecyclerView

    在弄android刷新的时候,可算是耗费了一番功夫,最后发觉有现成的控件,并且非常好用,这里记录一下. 原文是 https://blog.csdn.net/huangxin112/article/de ...

  3. juery下拉刷新,div加载更多元素并添加点击事件(二)

    buffer.append("<div class='col-xs-3 "+companyId+"' style='padding-left: 10px; padd ...

  4. Android如何定制一个下拉刷新,上滑加载更多的容器

    前言 下拉刷新和上滑加载更多,是一种比较常用的列表数据交互方式. android提供了原生的下拉刷新容器 SwipeRefreshLayout,可惜样式不能定制. 于是打算自己实现一个专用的.但是下拉 ...

  5. 移动端下拉刷新上拉加载-mescroll.js插件

    最近无意间看到有这么一个上拉刷新下拉加载的插件 -- mescroll.js,个人感觉挺好用的,官网地址是:http://www.mescroll.com 然后我就看了一下文档,简单的写了一个小dem ...

  6. Android 自定义 ListView 上下拉动“刷新最新”和“加载更多”歌曲列表

    本文内容 环境 测试数据 项目结构 演示 参考资料 本文演示,上拉刷新最新的歌曲列表,和下拉加载更多的歌曲列表.所谓"刷新最新"和"加载更多"是指日期.演示代码 ...

  7. RecyclerView下拉刷新上拉加载(三)—对Adapter的封装

    RecyclerView下拉刷新上拉加载(一) http://blog.csdn.net/baiyuliang2013/article/details/51506036 RecyclerView下拉刷 ...

  8. react-native 自定义 下拉刷新 / 上拉加载更多 组件

    1.封装 Scroller 组件 /** * 下拉刷新/上拉加载更多 组件(Scroller) */ import React, {Component} from 'react'; import { ...

  9. vue10行代码实现上拉翻页加载更多数据,纯手写js实现下拉刷新上拉翻页不引用任何第三方插件

    vue10行代码实现上拉翻页加载更多数据,纯手写js实现下拉刷新上拉翻页不引用任何第三方插件/库 一提到移动端的下拉刷新上拉翻页,你可能就会想到iScroll插件,没错iScroll是一个高性能,资源 ...

随机推荐

  1. k8s通过secret管理敏感信息

    应用启动过程中可能需要一些敏感信息,比如访问数据库的用户名密码或者秘钥.将这些信息直接保存在容器镜像中显然不妥,Kubernetes 提供的解决方案是 Secret. Secret 会以密文的方式存储 ...

  2. 《锋利的JQuery》读书要点笔记4——表格表单的操作

    第五章 jQuery对表单,表格的操作以及更多应用 这章主要以一些具体案例讲解了jQuery对表单,表格的常用操作,以及一些常见的jQuery应用,用到的都是上几章说的东西.下面就以具体的案例来展开. ...

  3. JAVA MAC 配置

    1下载对应的JDK,并安装 查看是否成功 java -version 2配置环境变量 sudo vim /etc/profile 入一下内容: JAVA_HOME="/Library/Jav ...

  4. [libgdx游戏开发教程]使用Libgdx进行游戏开发(6)-添加主角和道具

    如前所述,我们的主角是兔子头.接下来我们实现它. 首先对AbstractGameObject添加变量并初始化: public Vector2 velocity; public Vector2 term ...

  5. HDU 2824.The Euler function-筛选法求欧拉函数

    欧拉函数: φ(n)=n*(1-1/p1)(1-1/p2)....(1-1/pk),其中p1.p2…pk为n的所有素因子.比如:φ(12)=12*(1-1/2)(1-1/3)=4.可以用类似求素数的筛 ...

  6. Storm学习中遇到的问题整理

    在编写storm代码来进行实时分析的时候遇到了一些问题,有些的确令人比较头痛,现在稍微做一下整理.数据流向(本地-Spout-Bolt-Hdfs) 1数据的输入输出文件的路径选择 因为在此项目中数据是 ...

  7. [BZOJ 1293] 生日礼物

    Link: BZOJ 1293 传送门 Solution: 这题直接上尺取法就行了吧 先将每种颜色第一个放入优先队列,用$mx$维护当前的末尾位置 每次取出第一个颜色,更新答案.将其下一个放入队列中去 ...

  8. python3 开发面试题(创建表结构)6.9

    纯sql语句写出: '''设计 图书管理系统 表结构: - 书 - 书名 - 作者 - 姓名 - 出版社 - 出版社名称 - 地址 一本书只能由一家出版社出版 --> 多对一(书对出版社) 一本 ...

  9. 使用Python的turtle模块画出简单的柱状图

    代码如下: import turtle heights = [856, 420,360,260,205] def main(): t = turtle.Turtle() t.hideturtle() ...

  10. iOS数据库操作(使用FMDB)

    iOS中原生的SQLite API在使用上相当不友好,在使用时,非常不便.于是,就出现了一系列将SQLite API进行封装的库,例如FMDB.PlausibleDatabase.sqlitepers ...