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具有划时 ...
随机推荐
- HTML5 <li> <ol> <ul> 用法
定义和用法 <li> 标签定义列表项目. <li> 标签可用在有序列表 (<ol>) 和无序列表 (<ul>) 中. HTML 与 XHTML 之间的差 ...
- ActiveMQ broker和客户端之间的确认
生产者发送消息:producer ---------> broker broker返回确认:broker ---------> producer 生产者发送同步消息,broker会返回Re ...
- Python3+telnetlib实现telnet客户端
一.程序要点说明 python实现telnet客户端的六个关键问题及其答案是: 使用什么库实现telnet客户端----telnetlib 怎么连接主机----两种方法,一种是在实例化时传入ip地址连 ...
- ftp/sftp定时自动上传文件脚本(CentOS)
1.ftp自动上传文件脚本 #!/bin/bash ftp -n<<! open 192.168.220.129 user ls toor binary hash cd /path/to/ ...
- Net Core2.0 升级到.Net Core 2.1
1. 安装新 .Net Core SDK 2.1 2. 升级VS.net 到15.7, 这个版本极其不好用,IIS打中文会自动退出,但现在也没办法降级了.只能等微软打补丁. 3. 对于面向 ASP.N ...
- Weka里如何将arff文件或csv文件批量导入MySQL数据库(六)
这里不多说,直接上干货! 前提博客是 Weka中数据挖掘与机器学习系列之数据格式ARFF和CSV文件格式之间的转换(四) 1.将arff文件批量导入MySQL数据库 我在这里,arff文件以Weka安 ...
- 尚学堂java答案解析 第三章
本答案为本人个人编辑,仅供参考,如果读者发现,请私信本人或在下方评论,提醒本人修改 一.选择题 1.A 2.BD 解析:switch的的判断表达式的数据类型:byte short int ch ...
- .NET接入UnionPay银联支付(一)手机wap支付
最近呢,比较忙,公司在接入银联全渠道支付,博主接手的wap支付,发表一下博主在接入的时候遇到的坑和注意事项,方便大家学习接入,爬坑的路上更顺利一点~ 开发步骤 1. 以表单的方式组装要发送给银联全渠道 ...
- 对大学生学习Linux系统的七项实用建议
你现在的工作是你所渴望的理想工作吗?或者说这只是你整个职业生涯中的一段插曲?虽然我们每个人都不一定能够说出自己所想的是什么,但是我们心里其实跟明镜似的.相信许多人对于自己喜好的工作投入精力不会有问题, ...
- Python之路-python基础一
本章内容: 一.编程语言分类 二.python之变量介绍 三.python交互命令(input,print,getpass) 四.Python之循环控制 ...