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具有划时 ...
随机推荐
- UI基础一:简单的BOL查询
利用标准的BOL编辑工具,添加BOL对象,重写查询方法,实现简答的BOL查询 1.SE11创建查询对象结构: 2.SE11创建查询结果对象: 3.SE24新建处理类: 重写查询结果方法: METHOD ...
- springmvc访问项目默认先访问后台再返回首页
1.spring过滤的url-pattern设置成了/,所以这里随便给个新的后缀 <welcome-file-list> <welcome-file>index.zl</ ...
- PHP手册-函数参考-加密扩展
一.Crack.CSPRNG.Hash.Mcrypt.Mhash.OpenSSL.密码散列算法的对比 Crack CSPRNG Hash Mcrypt Mhash OpenSSL 密码散列算法 简 ...
- Vue keep-alive总结
<keep-alive>是Vue的内置组件,能在组件切换过程中将状态保留在内存中,防止重复渲染DOM. <keep-alive> 包裹动态组件时,会缓存不活动的组件实例,而不是 ...
- 关于RabbitMQ服务器整合(二)
准备工作 15min IDEA maven 3.0 在开始构建项目之前,机器需要安装rabbitmq,你可以去官网下载,http://www.rabbitmq.com/download.html ,如 ...
- css 解决fixed 布局下不能滚动的问题
如果我们布局的是后是fixed并且想要高度为100%的时候,我们一般会这样设置: div { display:fixed; height:%; overflow:scroll; } 但是这样并不会出现 ...
- python全栈开发笔记--------条件语句
Python条件语句是通过一条或多条语句的执行结果(True或者False)来决定执行的代码块. Python程序语言指定任何非0和非空(null)值为true,0 或者 null为false. Py ...
- MySQL5.6数据库8小时内无请求自动断开连接
问题: 最近的项目中,发现Mysql数据库在8个小时内,没有请求时,会自动断开连接,这是MySQL服务器的问题.The last packet successfully received from t ...
- vue-router-7-重定向及别名
const router = new VueRouter({ mode: 'history', base: __dirname, routes: [ { path: '/', component: H ...
- 《Python》re模块补充、异常处理
一.re模块 1.match方法 import re # match 验证用户输入的内容 ret = re.match('\d+', 'hhoi2342ho12ioh11') print(ret) # ...