React-Native 之 GD (七)下拉刷新 及 上拉加载更多
1.下拉刷新 使用第三方插件
下载插件:
$ npm install react-native-pull@latest --save
引入:
import {PullList} from 'react-native-pull';
将 ListView 改为 PullList 即可
GDHalfHourHot.js
/**
* 近半小时热门
*/
import React, { Component } from 'react';
import {
StyleSheet,
Text,
View,
TouchableOpacity,
Image,
ListView,
Dimensions,
DeviceEventEmitter,
} from 'react-native'; // 获取屏幕宽高
const {width, height} = Dimensions.get('window'); // 引入自定义导航栏组件
import CommunalNavBar from '../main/GDCommunalNavBar';
// 引入 cell
import CommunalHotCell from '../main/GDCommunalHotCell';
// 引入 空白页组件
import NoDataView from '../main/GDNoDataView';
// 引入 下拉刷新组件
import {PullList} from 'react-native-pull'; export default class GDHalfHourHot extends Component { // 构造
constructor(props) {
super(props);
// 初始状态
this.state = {
dataSource: new ListView.DataSource({rowHasChanged:(r1, r2) => r1 !== r2}), // 数据源 优化
loaded: false, // 用于判断是否显示空白页
};
// 绑定
this.fetchData = this.fetchData.bind(this);
} // 网络请求
fetchData(resolve) {
// 测试没用数据的情况
setTimeout(() => {
fetch('http://guangdiu.com/api/gethots.php') // 请求地址
.then((response) => response.json()) // 定义名称 将数据转为json格式
.then((responseData) => { // 处理数据
// 修改dataSource的值
this.setState({
dataSource: this.state.dataSource.cloneWithRows(responseData.data),
loaded:true,
});
// 关闭下来刷新动画
if (resolve !== undefined) {
// 使用定时器 延时关闭动画
setTimeout(() => {
resolve();
},1000);
}
})
.done(); // 结束
},3000)
} // 跳回首页
popToHome() {
this.props.navigator.pop();
} // 返回中间按钮
renderTitleItem() {
return(
<Text style={styles.navbarTitleItemStyle}>近半小时热门</Text>
);
} // 返回右边按钮
renderRightItem() {
return(
<TouchableOpacity
onPress={() => {this.popToHome()}}
>
<Text style={styles.navbarRightItemStyle}>关闭</Text>
</TouchableOpacity>
);
} // 判断显示列表 还是 显示空白页
renderListView() {
if(this.state.loaded === false) {
// 显示空白页
return(
<NoDataView />
);
}else{
return(
<PullList // 将ListView 改为 PullList
// 下拉刷新
onPullRelease={(resolve) => this.fetchData(resolve)}
// 数据源 通过判断dataSource是否有变化,来判断是否要重新渲染
dataSource={this.state.dataSource}
renderRow={this.renderRow}
// 隐藏水平线
showsHorizontalScrollIndicator={false}
style={styles.listViewStyle}
initialListSize={5}
// 返回 listView 头部
renderHeader={this.renderHeader}
/>
);
}
} // 返回 listView 头部
renderHeader() {
return(
<View style={styles.headerPromptStyle}>
<Text>根据每条折扣的点击进行统计,每5分钟更新一次</Text>
</View>
);
} // 返回每一行cell的样式
renderRow(rowData) {
// 使用cell组件
return(
<CommunalHotCell
image={rowData.image}
title={rowData.title}
/>
);
} componentWillMount() {
// 向GDMain.js 发送通知 隐藏tabBar
DeviceEventEmitter.emit('isHiddenTabBar', true);
} componentWillUnmount() {
// 向GDMain.js 发送通知 显示tabBar
DeviceEventEmitter.emit('isHiddenTabBar', false);
} // 生命周期 组件渲染完成 已经出现在dom文档里
componentDidMount() {
// 请求数据
this.fetchData();
} render() {
return (
<View style={styles.container}>
{/* 导航栏样式 */}
<CommunalNavBar
titleItem = {() => this.renderTitleItem()}
rightItem = {() => this.renderRightItem()}
/> {/* 根据网络状态决定是否渲染 listView */}
{this.renderListView()}
</View>
);
}
} const styles = StyleSheet.create({
container: {
flex:1,
alignItems: 'center',
}, navbarTitleItemStyle: {
fontSize:17,
color:'black',
marginLeft:50
},
navbarRightItemStyle: {
fontSize:17,
color:'rgba(123,178,114,1.0)',
marginRight:15
}, headerPromptStyle: {
height:44,
width:width,
backgroundColor:'rgba(239,239,239,0.5)',
justifyContent:'center',
alignItems:'center'
}, listViewStyle: {
width:width,
}
});
效果图:

2.POST 带参数请求
// 网络请求
fetchData(resolve) {
// 初始化 formData
let formData = new FormData();
// 添加参数
formData.append("count","5");
formData.append("mall","京东商城"); // 测试没用数据的情况
setTimeout(() => {
fetch('http://guangdiu.com/api/getlist.php', { // url 请求网址
method: 'POST', // 请求方式
headers:{}, // 设置请求头(默认为空对象)
body:formData, // 将formData传给body
})
.then((response) => response.json()) // 定义名称 将数据转为json格式
.then((responseData) => { // 处理数据
// 修改dataSource的值
this.setState({
dataSource: this.state.dataSource.cloneWithRows(responseData.data),
loaded:true,
});
// 关闭下来刷新动画
if (resolve !== undefined) {
// 使用定时器 延时关闭动画
setTimeout(() => {
resolve();
},1000);
}
})
.done(); // 结束
});
}
3.navigator 跳转动画 关闭 Navigator 返回手势
有时候我们需要在跳转的时候使用不同的跳转动画,比如我们 半小时热门 的跳转方式在 iOS 内叫 模态跳转,特性就是当页面退出后会直接销毁,多用于注册、登录等不需要常驻内存的界面。
react-native 中为了方便实现这样的功能,我们可以在初始化 Navigator 的时候,在 ‘configsSence’ 中进行操作;具体操作如下:
// 设置Navigator跳转动画
setNavAnimationType(route) {
if(route.animationType) { // 外部有值传入
// 关闭返回手势
let conf = route.animationType;
conf.gestures = null;
return conf;
}else{
// 默认动画
return Navigator.SceneConfigs.PushFromRight;
}
}
<Navigator
// 设置路由
initialRoute = {
{
name: selectedTab,
component: component
}
} // 设置导航动画
configureScene={(route) => this.setNavAnimationType(route)} renderScene = {
(route, navigator) => {
let Component = route.component;
return <Component {...route.params} navigator={navigator} />
}
} />
这样我们在需要跳转的地方只需要传入相应的参数即可。
// 跳转到近半小时热门
pushToHalfHourHot() {
// this.props 可以获取所有组件属性
this.props.navigator.push({
component: HalfHourHot,
// 设置调整动画
animationType: Navigator.SceneConfigs.FloatFromBottom,
})
}
4.上拉加载更多
react-native-pull 框架的上拉加载使用也很简单,配合 onEndReached、onEndReachedThreshold、renderFooter使用
GDHome.js
/**
* 首页
*/
import React, { Component } from 'react';
import {
StyleSheet,
Text,
View,
TouchableOpacity,
Image,
ListView,
Dimensions,
ActivityIndicator,
} from 'react-native'; // 引入 下拉刷新组件
import {PullList} from 'react-native-pull';
// 导航器
import CustomerComponents, {
Navigator
} from 'react-native-deprecated-custom-components'; // 获取屏幕宽高
const {width, height} = Dimensions.get('window'); // 引入自定义导航栏组件
import CommunalNavBar from '../main/GDCommunalNavBar';
// 引入 近半小时热门组件
import HalfHourHot from './GDHalfHourHot';
// 引入 搜索页面组件
import Search from './GDSearch';
// 引入 cell
import CommunalHotCell from '../main/GDCommunalHotCell';
// 引入 空白页组件
import NoDataView from '../main/GDNoDataView'; export default class GDHome extends Component { // 构造
constructor(props) {
super(props);
// 初始状态
this.state = {
dataSource: new ListView.DataSource({rowHasChanged:(r1, r2) => r1 !== r2}), // 数据源 优化
loaded: false, // 用于判断是否显示空白页
};
// 绑定
this.fetchData = this.fetchData.bind(this);
this.loadMore = this.loadMore.bind(this);
} // 网络请求
fetchData(resolve) {
// 初始化 formData
let formData = new FormData();
// 添加参数
formData.append("count","5");
formData.append("mall","京东商城"); // 测试没用数据的情况
setTimeout(() => {
fetch('http://guangdiu.com/api/getlist.php', { // url 请求网址
method: 'POST', // 请求方式
headers:{}, // 设置请求头(默认为空对象)
body:formData, // 将formData传给body
})
.then((response) => response.json()) // 定义名称 将数据转为json格式
.then((responseData) => { // 处理数据
// 修改dataSource的值
this.setState({
dataSource: this.state.dataSource.cloneWithRows(responseData.data),
loaded:true,
});
// 关闭下来刷新动画
if (resolve !== undefined) {
// 使用定时器 延时关闭动画
setTimeout(() => {
resolve();
},1000);
}
})
.done(); // 结束
});
} // 跳转到近半小时热门
pushToHalfHourHot() {
// this.props 可以获取所有组件属性
this.props.navigator.push({
component: HalfHourHot,
// 设置调整动画
animationType: Navigator.SceneConfigs.FloatFromBottom,
})
} // 跳转到搜索页面
pushToSearch() {
this.props.navigator.push({
component: Search,
})
} // 返回左边按钮
renderLeftItem() {
// 将组件返回出去
return(
<TouchableOpacity
onPress={() => {this.pushToHalfHourHot()}}
>
<Image source={{uri:'hot_icon_20x20'}} style={styles.navbarLeftItemStyle} />
</TouchableOpacity>
);
} // 返回中间按钮
renderTitleItem() {
return(
<TouchableOpacity>
<Image source={{uri:'navtitle_home_down_66x20'}} style={styles.navbarTitleItemStyle} />
</TouchableOpacity>
);
} // 返回右边按钮
renderRightItem() {
return(
<TouchableOpacity
// 跳转搜索页面
onPress={() => {this.pushToSearch()}}
>
<Image source={{uri:'search_icon_20x20'}} style={styles.navbarRightItemStyle} />
</TouchableOpacity>
);
} // 加载更多
loadMore() {
fetch('http://guangdiu.com/api/gethots.php') // 请求地址
.then((response) => response.json()) // 定义名称 将数据转为json格式
.then((responseData) => { // 处理数据
// 修改dataSource的值
this.setState({
dataSource: this.state.dataSource.cloneWithRows(responseData.data),
loaded:true,
});
})
.done(); // 结束
} renderFooter() {
return (
<View style={{height: 100}}>
<ActivityIndicator />
</View>
);
} // 根据网络状态决定是否渲染 listView
renderListView() {
if(this.state.loaded === false) {
// 显示空白页
return(
<NoDataView />
);
}else{
return(
<PullList // 将ListView 改为 PullList
// 下拉刷新
onPullRelease={(resolve) => this.fetchData(resolve)}
// 数据源 通过判断dataSource是否有变化,来判断是否要重新渲染
dataSource={this.state.dataSource}
renderRow={this.renderRow}
// 隐藏水平线
showsHorizontalScrollIndicator={false}
style={styles.listViewStyle}
initialListSize={5}
// 返回 listView 头部
renderHeader={this.renderHeader}
// 上拉加载更多
onEndReached={this.loadMore}
onEndReachedThreshold={60}
renderFooter={this.renderFooter}
/>
);
}
} // 返回每一行cell的样式
renderRow(rowData) {
// 使用cell组件
return(
<CommunalHotCell
image={rowData.image}
title={rowData.title}
/>
);
} // 生命周期 组件渲染完成 已经出现在dom文档里
componentDidMount() {
// 请求数据
this.fetchData();
} render() {
return (
<View style={styles.container}>
{/* 导航栏样式 */}
<CommunalNavBar
leftItem = {() => this.renderLeftItem()}
titleItem = {() => this.renderTitleItem()}
rightItem = {() => this.renderRightItem()}
/> {/* 根据网络状态决定是否渲染 listView */}
{this.renderListView()}
</View>
);
}
} const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
},
navbarLeftItemStyle: {
width:20,
height:20,
marginLeft:15,
},
navbarTitleItemStyle: {
width:66,
height:20,
},
navbarRightItemStyle: {
width:20,
height:20,
marginRight:15,
}, listViewStyle: {
width:width,
},
});
效果图:

React-Native 之 GD (七)下拉刷新 及 上拉加载更多的更多相关文章
- Android如何定制一个下拉刷新,上滑加载更多的容器
前言 下拉刷新和上滑加载更多,是一种比较常用的列表数据交互方式. android提供了原生的下拉刷新容器 SwipeRefreshLayout,可惜样式不能定制. 于是打算自己实现一个专用的.但是下拉 ...
- android ListView的上部下拉刷新下部点击加载更多具体实现及拓展
android ListView的上部下拉刷新下部点击加载更多具体实现及拓展 ListView下拉刷新,上拉自动加载更多 下拉刷新以及加载更多
- Android之下拉刷新,上啦加载的实现(一)
转载地址http://blog.csdn.net/leehong2005/article/details/12567757#t5 前段时间项目中用到了下拉刷新功能,之前在网上也找到过类似的demo,但 ...
- react + iscroll5 实现完美 下拉刷新,上拉加载
经过几天的反复折腾,总算做出一个体验还不错的列表页了,主要支持了下拉刷新,上拉加载两个功能. 一开始直接采用了react-iscroll插件,它是基于iscroll插件开发的组件.但是开发过程中,发现 ...
- 前端提升生产力系列三(vant3 vue3 移动端H5下拉刷新,上拉加载组件的封装)
| 在日常的移动端开发中,经常会遇到列表的展示,以及数据量变多的情况下还会有上拉和下拉的操作.进入新公司后发现移动端好多列表,但是在看代码的时候发现,每个列表都是单独的代码,没有任何的封装,都是通过v ...
- iOS MJRefresh下拉刷新(上拉加载)使用详解
下拉刷新控件目前比较火的有好几种,本人用过MJRefresh 和 SVPullToRefresh,相对而言,前者比后者可定制化.拓展新都更高一点. 因此本文着重讲一下MJRefresh的简单用法. 导 ...
- SVPullToRefresh 下拉刷新,上拉加载
https://github.com/Sephiroth87/ODRefreshControl 类似刷新控件,类似qq动画的那种刷新. 一.下载第三方库 https://github.com/samv ...
- 微信小程序开发之 下拉刷新,上拉加载更多
本文记载了如何在微信小程序里面实现下拉刷新,上拉加载更多 先开看一下界面 大致如此的界面吧. 这个Demo使用了微信的几个Api和事件,我先列出来. 1.wx.request (获取远程服务器的数据, ...
- iOS开发 XML解析和下拉刷新,上拉加载更多
iOS开发 XML解析和下拉刷新,上拉加载更多 1.XML格式 <?xml version="1.0" encoding="utf-8" ?> 表示 ...
- ListView下拉刷新、上拉载入更多之封装改进
在Android中ListView下拉刷新.上拉载入更多示例一文中,Maxwin兄给出的控件比较强大,前面有详细介绍,但是有个不足就是,里面使用了一些资源文件,包括图片,String,layout,这 ...
随机推荐
- [BZOJ 4025]二分图(线段树分治+带边权并查集)
[BZOJ 4025]二分图(线段树分治+带边权并查集) 题面 给出一个n个点m条边的图,每条边会在时间s到t出现,问每个时间的图是否为一个二分图 \(n,m,\max(t_i) \leq 10^5\ ...
- 【PDF】手写字与识别字重叠
[PDF]手写字与识别字重叠 前言 同学平时上课用iPad记笔记,考试之前导出为PDF发给我后,我用PDF打开,发现可以直接Ctrl+F搜索一些词语.一直不知道是怎么做到的,毕竟里面的字都是手写的,不 ...
- 剑指offer-二叉搜索树的后序遍历序列-python
题目描述 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则输出Yes,否则输出No.假设输入的数组的任意两个数字都互不相同. 递归法: 先判断左子树是否存在 再判断右子树是否存 ...
- js工厂函数创建对象与对象构造函数的理解
工厂函数,顾名思义,就是通过一个"工厂的加工" 来创建一个对象的函数 //工厂函数 function createPerson(name,sex){ sex = sex == '男' ? '女' : ...
- debian利用snmp监控服务器异常状态
1.安装snmp apt-get install snmp snmpd 2.配置snmp vi /etc/snmp/snmpd.conf 注释15行 #agentAddress udp:127.0.0 ...
- Consider defining a bean of type 'org.springframework.web.client.RestTemplate' in your configuration
https://www.cnblogs.com/EasonJim/p/7546136.html 错误如下: ERROR 31473 --- [ main] o.s.b.d.LoggingFailure ...
- Linux下载:wget、yum与apt-get用法及区别
一般来说著名的linux系统基本上分两大类: RedHat系列:Redhat.Centos.Fedora等 Debian系列:Debian.Ubuntu等 RedHat 系列 常见的安装包格式 rpm ...
- CQRS架构下的Saga流程重构
- 前端每日实战:11# 视频演示如何用纯 CSS 创作一个荧光脉冲 loader 特效
效果预览 按下右侧的"点击预览"按钮在当前页面预览,点击链接全屏预览. https://codepen.io/zhang-ou/pen/erRzzR 可交互视频教程 此视频是可以交 ...
- 为何使用Shell脚本
为何使用Shell脚本 分类: linux shell脚本学习2012-09-12 17:18 78人阅读 评论(0) 收藏 举报 shell脚本任务工作 s h e l l 脚本在处 ...