react-native 自定义 下拉刷新 / 上拉加载更多 组件
1.封装 Scroller 组件
/**
* 下拉刷新/上拉加载更多 组件(Scroller)
*/
import React, {Component} from 'react';
import {
StyleSheet,
Text,
View,
ListView,
ActivityIndicator,
RefreshControl,
} from 'react-native'; export default class Scroller extends Component {
// 构造函数
constructor(props) {
super(props);
this.state = {
//
}
} render() {
const { dataSource, renderRow, isRefreshing } = this.props;
// console.log(this.props); return (
<View style={styles.container}>
{/*列表数据*/}
<ListView
// 数据源
dataSource={dataSource}
// 从数据源(dataSource)中接受一条数据,以及它和它所在section的ID
renderRow={renderRow}
// 页头与页脚会在每次渲染过程中都重新渲染(允许在ListView底部增加一栏,便于显示加载动画)
renderFooter={this._renderFooter.bind(this)}
// 当所有的数据都已经渲染过,并且列表被滚动到距离最底部不足onEndReachedThreshold个像素的距离时调用
onEndReached={this._fetchMoreData.bind(this)}
// 调用onEndReached之前的临界值,单位是像素。(预加载)
onEndReachedThreshold={}
// 隐藏右侧滚动条
showsVerticalScrollIndicator={false}
// finished warning : in next release ...
enableEmptySections={true}
// 自动调整迁移内容
// 导航栏或标签栏或工具栏不覆盖 Scrollview 内容
// 去除默认定位间距
automaticallyAdjustContentInsets={false}
// 下拉刷新
refreshControl={
<RefreshControl
// 是否刷新
refreshing={isRefreshing}
onRefresh={this._onRefresh.bind(this)}
tintColor={"#ff6600"}
title={"拼命加载中..."}
/>
}
/>
</View>
)
} /**
* 下拉刷新
*/
_onRefresh() {
// console.log('下拉刷新');
if (this.props.isRefreshing || !this._hasMore()) {
return
}
// 向后台发送 '0',告知刷新操作
this.props.fetchData();
} /**
* 加 _ 代表私有方法
* 上拉加载更多
*/
_fetchMoreData() {
// console.log('上拉加载更多');
/**
* this._hasMore() 验证还有更多数据
* isLoadingTail true/false 加载动画(菊花图)
*/
if (!this._hasMore() || this.props.isLoadingTail) {
return
}
let page = this.props.cachedResults.nextPage;
this.props.fetchData(page);
} /**
* 验证还有更多数据
*/
_hasMore() {
return this.props.cachedResults.items.length !== this.props.cachedResults.items.total;
} /**
* 底部加载动画 及 没有更多数据文本(ListView底部增加一栏,便于显示加载动画)
*/
_renderFooter() {
if (!this._hasMore() && this.props.cachedResults.total !== ) {
return (
<View style={styles.loadingMore}>
<Text style={styles.loadingText}>没有更多了</Text>
</View>
)
} if (!this.props.isLoadingTail) {
return (
<View style={styles.loadingMore}></View>
)
} // 菊花图
return (
<ActivityIndicator style={styles.loadingMore}/>
)
} } // 样式
const styles = StyleSheet.create({
container: {
flex: ,
backgroundColor: '#F5FCFF',
},
// 菊花图
loadingMore: {
marginVertical:
},
// 文案样式
loadingText: {
color: '#777',
textAlign: 'center'
}
});
2.页面调用
/**
* 视频列表页
*/
import React, {Component} from 'react';
import {
StyleSheet,
Text,
View,
ImageBackground,
ListView,
TouchableHighlight,
Alert,
Dimensions,
ActivityIndicator,
RefreshControl,
} from 'react-native';
// 下拉刷新/上拉加载更多组件
import Scroller from '../../components/Scroller';
// 图标
import Icon from 'react-native-vector-icons/Ionicons';
// item 组件
import CreationItem from '../../components/CreationItem';
import config from '../../common/config';
import request from '../../common/request'; let {width} = Dimensions.get("window"); // 缓存列表中所有数据
let cachedResults = {
nextPage: , // 下一页
items: [], // listview 数据(视频列表)
total: // 总数
}; export default class List extends Component {
// 构造函数
constructor() {
super();
let ds = new ListView.DataSource({
// 比较两条数据是否是一样的,来判断数据是否发生改变
rowHasChanged: (r1, r2) => r1 !== r2
});
this.state = {
dataSource: ds.cloneWithRows([]),
isLoadingTail: false, // loading?
isRefreshing: false // refresh?
}
} render() {
return (
<View style={styles.container}>
{/*顶部标题栏*/}
<View style={styles.header}>
<Text style={styles.headerTitle}>列表页面</Text>
</View>
{/*列表数据*/}
<Scroller
// 数据源
dataSource={this.state.dataSource}
// 渲染item(子组件)
renderRow={this._renderRow.bind(this)}
// 是否可以刷新
isRefreshing={this.state.isRefreshing}
// 是否可以加载更多
isLoadingTail={this.state.isLoadingTail}
// 请求数据
fetchData={this._fetchData.bind(this)}
// 缓存列表数据
cachedResults={cachedResults}
/>
</View>
)
} // 生命周期-组件挂载完毕 请求数据
componentDidMount() {
this._fetchData();
} // 请求数据
_fetchData(page) {
let that = this; if (page !== ) { // 加载更多操作
this.setState({
isLoadingTail: true
});
} else { // 刷新操作
this.setState({
isRefreshing: true
});
// 初始哈 nextPage
cachedResults.nextPage = ;
} request
.get(config.api.base + config.api.creations, {
accessToken: 'abc'
})
// data 变化的新数据
.then((data) => {
if (data.success) {
// 保存原数据
let items = cachedResults.items.slice();
if (page !== ) { // 加载更多操作
// 数组拼接
items = items.concat(data.data);
cachedResults.nextPage += ;
} else { // 刷新操作
// 数据不变
items = data.data;
} cachedResults.items = items; // 视频列表数据
cachedResults.total = data.total; // 总数 setTimeout(function () {
if (page !== ) { // 加载更多操作
that.setState({
isLoadingTail: false,
dataSource: that.state.dataSource.cloneWithRows(cachedResults.items)
});
} else { // 刷次操作
that.setState({
isRefreshing: false,
dataSource: that.state.dataSource.cloneWithRows(cachedResults.items)
});
}
}, );
}
})
.catch((error) => {
if (page !== ) { // 上拉加载更多操作
this.setState({
isLoadingTail: false
});
} else {
this.setState({ // 刷新操作
isRefreshing: false
});
}
console.error(error);
});
} // 列表 Item
_renderRow(row) {
const { navigation } = this.props;
return (
<CreationItem
navigation={navigation}
key={row.id} // 子组件唯一性
row={row}
/>
)
}
} // 样式
const styles = StyleSheet.create({
container: {
flex: ,
backgroundColor: '#F5FCFF',
},
// 头部样式
header: {
paddingTop: ,
paddingBottom: ,
backgroundColor: '#ee735c',
},
// 头部title样式
headerTitle: {
color: '#fff',
fontSize: ,
textAlign: 'center',
fontWeight: ''
},
// 菊花图
loadingMore: {
marginVertical:
},
// 文案样式
loadingText: {
color: '#777',
textAlign: 'center'
}
});
react-native 自定义 下拉刷新 / 上拉加载更多 组件的更多相关文章
- 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 ...
- 移动端下拉刷新上拉加载-mescroll.js插件
最近无意间看到有这么一个上拉刷新下拉加载的插件 -- mescroll.js,个人感觉挺好用的,官网地址是:http://www.mescroll.com 然后我就看了一下文档,简单的写了一个小dem ...
- Android如何定制一个下拉刷新,上滑加载更多的容器
前言 下拉刷新和上滑加载更多,是一种比较常用的列表数据交互方式. android提供了原生的下拉刷新容器 SwipeRefreshLayout,可惜样式不能定制. 于是打算自己实现一个专用的.但是下拉 ...
- Android 自定义 ListView 上下拉动“刷新最新”和“加载更多”歌曲列表
本文内容 环境 测试数据 项目结构 演示 参考资料 本文演示,上拉刷新最新的歌曲列表,和下拉加载更多的歌曲列表.所谓"刷新最新"和"加载更多"是指日期.演示代码 ...
- react-native-page-listview使用方法(自定义FlatList/ListView下拉刷新,上拉加载更多,方便的实现分页)
react-native-page-listview 对ListView/FlatList的封装,可以很方便的分页加载网络数据,还支持自定义下拉刷新View和上拉加载更多的View.兼容高版本Flat ...
- 使用MJRefresh自定义下拉刷新,上拉加载动画
有时候我们需要自己设置下拉刷新,上拉加载动画的实现,这里主要是记录下使用MJRefresh自定义下拉刷新,上拉加载动画..... 下拉刷新我们只需要继承MJRefreshGifHeader即可: 实现 ...
- 自定义ListView下拉刷新上拉加载更多
自定义ListView下拉刷新上拉加载更多 自定义RecyclerView下拉刷新上拉加载更多 Listview现在用的很少了,基本都是使用Recycleview,但是不得不说Listview具有划时 ...
随机推荐
- Hadoop 2.7.3 完全分布式维护-部署篇
测试环境如下 IP host JDK linux hadop role 172.16.101.55 sht-sgmhadoopnn-01 1.8.0_111 CentOS release ...
- mongodb副本集用户权限设置
mongodb副本集用户权限设置 用户权限参考文章 一:先看看MongoDB中用户的角色说明 read : 数据库的只读权限,包括: aggregate,checkShardingIndex, ...
- Redis 系列之CentOS下Redis的安装
前言 安装Redis需要知道自己需要哪个版本,有针对性的安装,比如如果需要redis GEO这个地理集合的特性,那么redis版本就不能低于3.2版本,由于这个特性是3.2版本才有的.另外需要注意的是 ...
- [luogu P2319] [HNOI2006]超级英雄
[luogu P2319] [HNOI2006]超级英雄 题目描述 现在电视台有一种节目叫做超级英雄,大概的流程就是每位选手到台上回答主持人的几个问题,然后根据回答问题的多少获得不同数目的奖品或奖金. ...
- ActiveMQ queue和topic,持久订阅和非持久订阅
消息的 destination 分为 queue 和 topic,而消费者称为 subscriber(订阅者).queue 中的消息只会发送给一个订阅者,而 topic 的消息,会发送给每一个订阅者. ...
- Linux svn的搭建和使用
搭建: http://www.cnblogs.com/aLittleBitCool/archive/2011/07/09/2101602.html 使用: http://www.cnblogs.com ...
- 小程序BindTap快速连续点击页面跳转多次
原因: 手机端点击Tap基础事件解决300ms延迟 解决办法: success 里面加一个延迟300ms能解决 setTimeout goRob(e) { const that = this retu ...
- nodejs 修改端口号 process.env.PORT(window环境下)
各个环境下,nodejs设置process.env.PORT的值的命令,如下1.linux环境下: PORT= node app.js 使用上面命令每次都需要重新设置,如果想设置一次永久生效,使用下面 ...
- Tomcat修改版本号教程(CentOS)
1 到apache-tomcat安装目录下的lib子文件夹,找到catalina.jar备份该文件然后将该文件下载到本地. 2 使用winrar等工具直接打开该jar包进入到org/apache/ca ...
- 生成PDF文档之iText
iTextSharp.text.Document:这是iText库中最常用的类,它代表了一个pdf实例.如果你需要从零开始生成一个PDF文件,你需要使用这个Document类.首先创建(new)该实例 ...