react-native 模仿原生 实现下拉刷新/上拉加载更多(RefreshListView)
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)的更多相关文章
- SwipeRefreshLayout实现下拉刷新上滑加载
1. 效果图 2.RefreshLayout.java package myapplication.com.myapplication; import android.content.Context; ...
- Android 下拉刷新上啦加载SmartRefreshLayout + RecyclerView
在弄android刷新的时候,可算是耗费了一番功夫,最后发觉有现成的控件,并且非常好用,这里记录一下. 原文是 https://blog.csdn.net/huangxin112/article/de ...
- juery下拉刷新,div加载更多元素并添加点击事件(二)
buffer.append("<div class='col-xs-3 "+companyId+"' style='padding-left: 10px; padd ...
- Android如何定制一个下拉刷新,上滑加载更多的容器
前言 下拉刷新和上滑加载更多,是一种比较常用的列表数据交互方式. android提供了原生的下拉刷新容器 SwipeRefreshLayout,可惜样式不能定制. 于是打算自己实现一个专用的.但是下拉 ...
- 移动端下拉刷新上拉加载-mescroll.js插件
最近无意间看到有这么一个上拉刷新下拉加载的插件 -- mescroll.js,个人感觉挺好用的,官网地址是:http://www.mescroll.com 然后我就看了一下文档,简单的写了一个小dem ...
- Android 自定义 ListView 上下拉动“刷新最新”和“加载更多”歌曲列表
本文内容 环境 测试数据 项目结构 演示 参考资料 本文演示,上拉刷新最新的歌曲列表,和下拉加载更多的歌曲列表.所谓"刷新最新"和"加载更多"是指日期.演示代码 ...
- RecyclerView下拉刷新上拉加载(三)—对Adapter的封装
RecyclerView下拉刷新上拉加载(一) http://blog.csdn.net/baiyuliang2013/article/details/51506036 RecyclerView下拉刷 ...
- react-native 自定义 下拉刷新 / 上拉加载更多 组件
1.封装 Scroller 组件 /** * 下拉刷新/上拉加载更多 组件(Scroller) */ import React, {Component} from 'react'; import { ...
- vue10行代码实现上拉翻页加载更多数据,纯手写js实现下拉刷新上拉翻页不引用任何第三方插件
vue10行代码实现上拉翻页加载更多数据,纯手写js实现下拉刷新上拉翻页不引用任何第三方插件/库 一提到移动端的下拉刷新上拉翻页,你可能就会想到iScroll插件,没错iScroll是一个高性能,资源 ...
随机推荐
- poj 1584(综合性强的计算几何,好题)
A Round Peg in a Ground Hole Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 6238 Acc ...
- poj 1654(利用叉积求面积)
Area Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 17937 Accepted: 4957 Description ...
- 关于ofbiz加载数据模块的文件参数配置
1,在applications文件夹下新建一个数据模块meetingroom 2, 要让ofbiz加载这个数据模块就需要在applications下的配置文件里修改参数 (1)在application ...
- 基于percona-monitoring-plugins实现Zabbix的MySQL多端口自动发现监控
https://blog.csdn.net/u013820054/article/details/50931793
- php使用memcached详解
一.memcached 简介 在很多场合,我们都会听到 memcached 这个名字,但很多同学只是听过,并没有用过或实际了解过,只知道它是一个很不错的东东.这里简单介绍一下,memcached 是高 ...
- 隐藏tomcat版本号
找到catalina.jar, cd /usr/local/tomcat/lib 解压catalina.jar unzip catalina.jar 会生成两个目录 修改配置文件:org/apache ...
- 山东省第六届省赛 BIGZHUGOD and His Friends II(赛瓦定理)
Description BIGZHUGOD and his three friends are playing a game in a triangle ground. The number of B ...
- Codeforces 723 A. The New Year: Meeting Friends
A. The New Year: Meeting Friends time limit per test 1 second memory limit per test 256 megabytes in ...
- HDU 2537 8球胜负(模拟)
/*这是一个模拟题,模拟一种台球的进球过程,并且判定胜负. 对于输入的字符串,如果出现R则红方记1分,如果出现Y则黄方记1分. 最后根据哪一方打进黑球和得分情况判定胜负. 程序说明: 这里给出两个C语 ...
- 训练指南 UVA - 11383(KM算法的应用 lx+ly >=w(x,y))
layout: post title: 训练指南 UVA - 11383(KM算法的应用 lx+ly >=w(x,y)) author: "luowentaoaa" cata ...