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. python类的__new__和__init__

    python的类,和其他语言有一点不太一样,就是,他把新建一个类和初始化一个类,分成了两个方法: __new__ __init__ 当然,想想就知道,肯定是__new__先发生,然后才是__init_ ...

  2. Submile text3 安装使用技巧

    第一次用submile text3,发现还是有一些东西需要配置的,而且submile text3是最近发布的,和原来的submile text2还是有一些区别的.这两天自己配置了一下,用起来感觉还是不 ...

  3. [centos6.5] yum makecache 连接错误的解决办法

    http://mirrors.163.com/.help/centos.html 访问这个就懂了

  4. centos opera 卸载

    /usr/local/bin/uninstall-opera

  5. python 面向对象(成员,静态,类)的(变量,方法)区别

    静态方法是使用@staticmethod装饰的方法,并且参数表中不需要self或者cls,可以访问类成员变量 默认的方法是有self的,是成员方法,可以访问私有变量和方法(通过self.xxx),或者 ...

  6. luogu P1938找工就业

    一头牛在一个城市最多只能赚D元,然后它必须到另一个城市工作.当然它可以在别处工作一阵子后,又回到原来的城市再最多赚D美元.而且这样的往返次数没有限制城市间有P条单向路径,共有C座城市,编号1~C,奶牛 ...

  7. 树状数组优化DP 【模拟赛】删区间

    哇,难受得一匹. 看到题的一瞬间竟然只想到了\(n^3\)的区间\(DP\) 一.\(40pts\) 设\(f[i][j]\)代表删去\(i\)到\(j\)这一段区间的最小代价和. 然后直接写普通的区 ...

  8. POJ 3250 Bad Hair Day(单调栈)

    [题目链接] http://poj.org/problem?id=3250 [题目大意] 有n头牛,每头牛都有一定的高度,他能看到在离他最近的比他高的牛前面的所有牛 现在每头牛往右看,问每头牛能看到的 ...

  9. [LOJ6436]神仙的游戏

    感觉border的性质还是挺神奇的 一个border的性质是$S$有长度为$len$的border当且仅当对$\forall i\equiv j\left(\bmod(n-len)\right)$有$ ...

  10. 【二分答案】【中位数】codeforces 394 bun

    bunDescription因为体育老师很喜欢等差数列,所以他要求学生们站队必须按身高站成等差数列.但是有些班级的学生无论如何也无法排成等差数列,于是体育老师从食堂买来了两种神奇的面包.吃一个第一种面 ...