1.下拉刷新  使用第三方插件

下载插件:

  1. $ npm install react-native-pull@latest --save

引入:

  1. import {PullList} from 'react-native-pull';

将 ListView 改为 PullList 即可

GDHalfHourHot.js

  1. /**
  2. * 近半小时热门
  3. */
  4. import React, { Component } from 'react';
  5. import {
  6. StyleSheet,
  7. Text,
  8. View,
  9. TouchableOpacity,
  10. Image,
  11. ListView,
  12. Dimensions,
  13. DeviceEventEmitter,
  14. } from 'react-native';
  15.  
  16. // 获取屏幕宽高
  17. const {width, height} = Dimensions.get('window');
  18.  
  19. // 引入自定义导航栏组件
  20. import CommunalNavBar from '../main/GDCommunalNavBar';
  21. // 引入 cell
  22. import CommunalHotCell from '../main/GDCommunalHotCell';
  23. // 引入 空白页组件
  24. import NoDataView from '../main/GDNoDataView';
  25. // 引入 下拉刷新组件
  26. import {PullList} from 'react-native-pull';
  27.  
  28. export default class GDHalfHourHot extends Component {
  29.  
  30. // 构造
  31. constructor(props) {
  32. super(props);
  33. // 初始状态
  34. this.state = {
  35. dataSource: new ListView.DataSource({rowHasChanged:(r1, r2) => r1 !== r2}), // 数据源 优化
  36. loaded: false, // 用于判断是否显示空白页
  37. };
  38. // 绑定
  39. this.fetchData = this.fetchData.bind(this);
  40. }
  41.  
  42. // 网络请求
  43. fetchData(resolve) {
  44. // 测试没用数据的情况
  45. setTimeout(() => {
  46. fetch('http://guangdiu.com/api/gethots.php') // 请求地址
  47. .then((response) => response.json()) // 定义名称 将数据转为json格式
  48. .then((responseData) => { // 处理数据
  49. // 修改dataSource的值
  50. this.setState({
  51. dataSource: this.state.dataSource.cloneWithRows(responseData.data),
  52. loaded:true,
  53. });
  54. // 关闭下来刷新动画
  55. if (resolve !== undefined) {
  56. // 使用定时器 延时关闭动画
  57. setTimeout(() => {
  58. resolve();
  59. },1000);
  60. }
  61. })
  62. .done(); // 结束
  63. },3000)
  64. }
  65.  
  66. // 跳回首页
  67. popToHome() {
  68. this.props.navigator.pop();
  69. }
  70.  
  71. // 返回中间按钮
  72. renderTitleItem() {
  73. return(
  74. <Text style={styles.navbarTitleItemStyle}>近半小时热门</Text>
  75. );
  76. }
  77.  
  78. // 返回右边按钮
  79. renderRightItem() {
  80. return(
  81. <TouchableOpacity
  82. onPress={() => {this.popToHome()}}
  83. >
  84. <Text style={styles.navbarRightItemStyle}>关闭</Text>
  85. </TouchableOpacity>
  86. );
  87. }
  88.  
  89. // 判断显示列表 还是 显示空白页
  90. renderListView() {
  91. if(this.state.loaded === false) {
  92. // 显示空白页
  93. return(
  94. <NoDataView />
  95. );
  96. }else{
  97. return(
  98. <PullList // 将ListView 改为 PullList
  99. // 下拉刷新
  100. onPullRelease={(resolve) => this.fetchData(resolve)}
  101. // 数据源 通过判断dataSource是否有变化,来判断是否要重新渲染
  102. dataSource={this.state.dataSource}
  103. renderRow={this.renderRow}
  104. // 隐藏水平线
  105. showsHorizontalScrollIndicator={false}
  106. style={styles.listViewStyle}
  107. initialListSize={5}
  108. // 返回 listView 头部
  109. renderHeader={this.renderHeader}
  110. />
  111. );
  112. }
  113. }
  114.  
  115. // 返回 listView 头部
  116. renderHeader() {
  117. return(
  118. <View style={styles.headerPromptStyle}>
  119. <Text>根据每条折扣的点击进行统计,每5分钟更新一次</Text>
  120. </View>
  121. );
  122. }
  123.  
  124. // 返回每一行cell的样式
  125. renderRow(rowData) {
  126. // 使用cell组件
  127. return(
  128. <CommunalHotCell
  129. image={rowData.image}
  130. title={rowData.title}
  131. />
  132. );
  133. }
  134.  
  135. componentWillMount() {
  136. // 向GDMain.js 发送通知 隐藏tabBar
  137. DeviceEventEmitter.emit('isHiddenTabBar', true);
  138. }
  139.  
  140. componentWillUnmount() {
  141. // 向GDMain.js 发送通知 显示tabBar
  142. DeviceEventEmitter.emit('isHiddenTabBar', false);
  143. }
  144.  
  145. // 生命周期 组件渲染完成 已经出现在dom文档里
  146. componentDidMount() {
  147. // 请求数据
  148. this.fetchData();
  149. }
  150.  
  151. render() {
  152. return (
  153. <View style={styles.container}>
  154. {/* 导航栏样式 */}
  155. <CommunalNavBar
  156. titleItem = {() => this.renderTitleItem()}
  157. rightItem = {() => this.renderRightItem()}
  158. />
  159.  
  160. {/* 根据网络状态决定是否渲染 listView */}
  161. {this.renderListView()}
  162. </View>
  163. );
  164. }
  165. }
  166.  
  167. const styles = StyleSheet.create({
  168. container: {
  169. flex:1,
  170. alignItems: 'center',
  171. },
  172.  
  173. navbarTitleItemStyle: {
  174. fontSize:17,
  175. color:'black',
  176. marginLeft:50
  177. },
  178. navbarRightItemStyle: {
  179. fontSize:17,
  180. color:'rgba(123,178,114,1.0)',
  181. marginRight:15
  182. },
  183.  
  184. headerPromptStyle: {
  185. height:44,
  186. width:width,
  187. backgroundColor:'rgba(239,239,239,0.5)',
  188. justifyContent:'center',
  189. alignItems:'center'
  190. },
  191.  
  192. listViewStyle: {
  193. width:width,
  194. }
  195. });

效果图:

2.POST 带参数请求

  1. // 网络请求
  2. fetchData(resolve) {
  3. // 初始化 formData
  4. let formData = new FormData();
  5. // 添加参数
  6. formData.append("count","5");
  7. formData.append("mall","京东商城");
  8.  
  9. // 测试没用数据的情况
  10. setTimeout(() => {
  11. fetch('http://guangdiu.com/api/getlist.php', { // url 请求网址
  12. method: 'POST', // 请求方式
  13. headers:{}, // 设置请求头(默认为空对象)
  14. body:formData, // 将formData传给body
  15. })
  16. .then((response) => response.json()) // 定义名称 将数据转为json格式
  17. .then((responseData) => { // 处理数据
  18. // 修改dataSource的值
  19. this.setState({
  20. dataSource: this.state.dataSource.cloneWithRows(responseData.data),
  21. loaded:true,
  22. });
  23. // 关闭下来刷新动画
  24. if (resolve !== undefined) {
  25. // 使用定时器 延时关闭动画
  26. setTimeout(() => {
  27. resolve();
  28. },1000);
  29. }
  30. })
  31. .done(); // 结束
  32. });
  33. } 

3.navigator 跳转动画   关闭 Navigator 返回手势

有时候我们需要在跳转的时候使用不同的跳转动画,比如我们 半小时热门 的跳转方式在 iOS 内叫 模态跳转,特性就是当页面退出后会直接销毁,多用于注册、登录等不需要常驻内存的界面。

react-native 中为了方便实现这样的功能,我们可以在初始化 Navigator 的时候,在 ‘configsSence’ 中进行操作;具体操作如下:

  1. // 设置Navigator跳转动画
  2. setNavAnimationType(route) {
  3. if(route.animationType) { // 外部有值传入
  4. // 关闭返回手势
  5. let conf = route.animationType;
  6. conf.gestures = null;
  7. return conf;
  8. }else{
  9. // 默认动画
  10. return Navigator.SceneConfigs.PushFromRight;
  11. }
  12. }
  1. <Navigator
  2. // 设置路由
  3. initialRoute = {
  4. {
  5. name: selectedTab,
  6. component: component
  7. }
  8. }
  9.  
  10. // 设置导航动画
  11. configureScene={(route) => this.setNavAnimationType(route)}
  12.  
  13. renderScene = {
  14. (route, navigator) => {
  15. let Component = route.component;
  16. return <Component {...route.params} navigator={navigator} />
  17. }
  18. } />

这样我们在需要跳转的地方只需要传入相应的参数即可。

  1. // 跳转到近半小时热门
  2. pushToHalfHourHot() {
  3. // this.props 可以获取所有组件属性
  4. this.props.navigator.push({
  5. component: HalfHourHot,
  6. // 设置调整动画
  7. animationType: Navigator.SceneConfigs.FloatFromBottom,
  8. })
  9. } 

4.上拉加载更多

react-native-pull 框架的上拉加载使用也很简单,配合 onEndReached、onEndReachedThreshold、renderFooter使用

GDHome.js

  1. /**
  2. * 首页
  3. */
  4. import React, { Component } from 'react';
  5. import {
  6. StyleSheet,
  7. Text,
  8. View,
  9. TouchableOpacity,
  10. Image,
  11. ListView,
  12. Dimensions,
  13. ActivityIndicator,
  14. } from 'react-native';
  15.  
  16. // 引入 下拉刷新组件
  17. import {PullList} from 'react-native-pull';
  18. // 导航器
  19. import CustomerComponents, {
  20. Navigator
  21. } from 'react-native-deprecated-custom-components';
  22.  
  23. // 获取屏幕宽高
  24. const {width, height} = Dimensions.get('window');
  25.  
  26. // 引入自定义导航栏组件
  27. import CommunalNavBar from '../main/GDCommunalNavBar';
  28. // 引入 近半小时热门组件
  29. import HalfHourHot from './GDHalfHourHot';
  30. // 引入 搜索页面组件
  31. import Search from './GDSearch';
  32. // 引入 cell
  33. import CommunalHotCell from '../main/GDCommunalHotCell';
  34. // 引入 空白页组件
  35. import NoDataView from '../main/GDNoDataView';
  36.  
  37. export default class GDHome extends Component {
  38.  
  39. // 构造
  40. constructor(props) {
  41. super(props);
  42. // 初始状态
  43. this.state = {
  44. dataSource: new ListView.DataSource({rowHasChanged:(r1, r2) => r1 !== r2}), // 数据源 优化
  45. loaded: false, // 用于判断是否显示空白页
  46. };
  47. // 绑定
  48. this.fetchData = this.fetchData.bind(this);
  49. this.loadMore = this.loadMore.bind(this);
  50. }
  51.  
  52. // 网络请求
  53. fetchData(resolve) {
  54. // 初始化 formData
  55. let formData = new FormData();
  56. // 添加参数
  57. formData.append("count","5");
  58. formData.append("mall","京东商城");
  59.  
  60. // 测试没用数据的情况
  61. setTimeout(() => {
  62. fetch('http://guangdiu.com/api/getlist.php', { // url 请求网址
  63. method: 'POST', // 请求方式
  64. headers:{}, // 设置请求头(默认为空对象)
  65. body:formData, // 将formData传给body
  66. })
  67. .then((response) => response.json()) // 定义名称 将数据转为json格式
  68. .then((responseData) => { // 处理数据
  69. // 修改dataSource的值
  70. this.setState({
  71. dataSource: this.state.dataSource.cloneWithRows(responseData.data),
  72. loaded:true,
  73. });
  74. // 关闭下来刷新动画
  75. if (resolve !== undefined) {
  76. // 使用定时器 延时关闭动画
  77. setTimeout(() => {
  78. resolve();
  79. },1000);
  80. }
  81. })
  82. .done(); // 结束
  83. });
  84. }
  85.  
  86. // 跳转到近半小时热门
  87. pushToHalfHourHot() {
  88. // this.props 可以获取所有组件属性
  89. this.props.navigator.push({
  90. component: HalfHourHot,
  91. // 设置调整动画
  92. animationType: Navigator.SceneConfigs.FloatFromBottom,
  93. })
  94. }
  95.  
  96. // 跳转到搜索页面
  97. pushToSearch() {
  98. this.props.navigator.push({
  99. component: Search,
  100. })
  101. }
  102.  
  103. // 返回左边按钮
  104. renderLeftItem() {
  105. // 将组件返回出去
  106. return(
  107. <TouchableOpacity
  108. onPress={() => {this.pushToHalfHourHot()}}
  109. >
  110. <Image source={{uri:'hot_icon_20x20'}} style={styles.navbarLeftItemStyle} />
  111. </TouchableOpacity>
  112. );
  113. }
  114.  
  115. // 返回中间按钮
  116. renderTitleItem() {
  117. return(
  118. <TouchableOpacity>
  119. <Image source={{uri:'navtitle_home_down_66x20'}} style={styles.navbarTitleItemStyle} />
  120. </TouchableOpacity>
  121. );
  122. }
  123.  
  124. // 返回右边按钮
  125. renderRightItem() {
  126. return(
  127. <TouchableOpacity
  128. // 跳转搜索页面
  129. onPress={() => {this.pushToSearch()}}
  130. >
  131. <Image source={{uri:'search_icon_20x20'}} style={styles.navbarRightItemStyle} />
  132. </TouchableOpacity>
  133. );
  134. }
  135.  
  136. // 加载更多
  137. loadMore() {
  138. fetch('http://guangdiu.com/api/gethots.php') // 请求地址
  139. .then((response) => response.json()) // 定义名称 将数据转为json格式
  140. .then((responseData) => { // 处理数据
  141. // 修改dataSource的值
  142. this.setState({
  143. dataSource: this.state.dataSource.cloneWithRows(responseData.data),
  144. loaded:true,
  145. });
  146. })
  147. .done(); // 结束
  148. }
  149.  
  150. renderFooter() {
  151. return (
  152. <View style={{height: 100}}>
  153. <ActivityIndicator />
  154. </View>
  155. );
  156. }
  157.  
  158. // 根据网络状态决定是否渲染 listView
  159. renderListView() {
  160. if(this.state.loaded === false) {
  161. // 显示空白页
  162. return(
  163. <NoDataView />
  164. );
  165. }else{
  166. return(
  167. <PullList // 将ListView 改为 PullList
  168. // 下拉刷新
  169. onPullRelease={(resolve) => this.fetchData(resolve)}
  170. // 数据源 通过判断dataSource是否有变化,来判断是否要重新渲染
  171. dataSource={this.state.dataSource}
  172. renderRow={this.renderRow}
  173. // 隐藏水平线
  174. showsHorizontalScrollIndicator={false}
  175. style={styles.listViewStyle}
  176. initialListSize={5}
  177. // 返回 listView 头部
  178. renderHeader={this.renderHeader}
  179. // 上拉加载更多
  180. onEndReached={this.loadMore}
  181. onEndReachedThreshold={60}
  182. renderFooter={this.renderFooter}
  183. />
  184. );
  185. }
  186. }
  187.  
  188. // 返回每一行cell的样式
  189. renderRow(rowData) {
  190. // 使用cell组件
  191. return(
  192. <CommunalHotCell
  193. image={rowData.image}
  194. title={rowData.title}
  195. />
  196. );
  197. }
  198.  
  199. // 生命周期 组件渲染完成 已经出现在dom文档里
  200. componentDidMount() {
  201. // 请求数据
  202. this.fetchData();
  203. }
  204.  
  205. render() {
  206. return (
  207. <View style={styles.container}>
  208. {/* 导航栏样式 */}
  209. <CommunalNavBar
  210. leftItem = {() => this.renderLeftItem()}
  211. titleItem = {() => this.renderTitleItem()}
  212. rightItem = {() => this.renderRightItem()}
  213. />
  214.  
  215. {/* 根据网络状态决定是否渲染 listView */}
  216. {this.renderListView()}
  217. </View>
  218. );
  219. }
  220. }
  221.  
  222. const styles = StyleSheet.create({
  223. container: {
  224. flex: 1,
  225. alignItems: 'center',
  226. },
  227. navbarLeftItemStyle: {
  228. width:20,
  229. height:20,
  230. marginLeft:15,
  231. },
  232. navbarTitleItemStyle: {
  233. width:66,
  234. height:20,
  235. },
  236. navbarRightItemStyle: {
  237. width:20,
  238. height:20,
  239. marginRight:15,
  240. },
  241.  
  242. listViewStyle: {
  243. width:width,
  244. },
  245. });

效果图:

React-Native 之 GD (七)下拉刷新 及 上拉加载更多的更多相关文章

  1. Android如何定制一个下拉刷新,上滑加载更多的容器

    前言 下拉刷新和上滑加载更多,是一种比较常用的列表数据交互方式. android提供了原生的下拉刷新容器 SwipeRefreshLayout,可惜样式不能定制. 于是打算自己实现一个专用的.但是下拉 ...

  2. android ListView的上部下拉刷新下部点击加载更多具体实现及拓展

    android ListView的上部下拉刷新下部点击加载更多具体实现及拓展 ListView下拉刷新,上拉自动加载更多 下拉刷新以及加载更多

  3. Android之下拉刷新,上啦加载的实现(一)

    转载地址http://blog.csdn.net/leehong2005/article/details/12567757#t5 前段时间项目中用到了下拉刷新功能,之前在网上也找到过类似的demo,但 ...

  4. react + iscroll5 实现完美 下拉刷新,上拉加载

    经过几天的反复折腾,总算做出一个体验还不错的列表页了,主要支持了下拉刷新,上拉加载两个功能. 一开始直接采用了react-iscroll插件,它是基于iscroll插件开发的组件.但是开发过程中,发现 ...

  5. 前端提升生产力系列三(vant3 vue3 移动端H5下拉刷新,上拉加载组件的封装)

    | 在日常的移动端开发中,经常会遇到列表的展示,以及数据量变多的情况下还会有上拉和下拉的操作.进入新公司后发现移动端好多列表,但是在看代码的时候发现,每个列表都是单独的代码,没有任何的封装,都是通过v ...

  6. iOS MJRefresh下拉刷新(上拉加载)使用详解

    下拉刷新控件目前比较火的有好几种,本人用过MJRefresh 和 SVPullToRefresh,相对而言,前者比后者可定制化.拓展新都更高一点. 因此本文着重讲一下MJRefresh的简单用法. 导 ...

  7. SVPullToRefresh​ 下拉刷新,上拉加载

    https://github.com/Sephiroth87/ODRefreshControl 类似刷新控件,类似qq动画的那种刷新. 一.下载第三方库 https://github.com/samv ...

  8. 微信小程序开发之 下拉刷新,上拉加载更多

    本文记载了如何在微信小程序里面实现下拉刷新,上拉加载更多 先开看一下界面 大致如此的界面吧. 这个Demo使用了微信的几个Api和事件,我先列出来. 1.wx.request (获取远程服务器的数据, ...

  9. iOS开发 XML解析和下拉刷新,上拉加载更多

    iOS开发 XML解析和下拉刷新,上拉加载更多 1.XML格式 <?xml version="1.0" encoding="utf-8" ?> 表示 ...

  10. ListView下拉刷新、上拉载入更多之封装改进

    在Android中ListView下拉刷新.上拉载入更多示例一文中,Maxwin兄给出的控件比较强大,前面有详细介绍,但是有个不足就是,里面使用了一些资源文件,包括图片,String,layout,这 ...

随机推荐

  1. UUID工具类及使用

    1.工具类: package UUIdtest; import java.util.UUID; public class UUIDUtil { public static String getUUID ...

  2. 《剑指offer》面试题24 二叉搜索树的后序遍历序列 Java版

    (判断一个元素均不相同的序列是否为一个BST的LRD) 书中方法:首先对于二叉搜索树,左子树中的所有元素小于根节点小于右子树中的所有元素,然后后序遍历序列最后一个元素是根节点,这是我们已知的条件.这道 ...

  3. uboot 主Makefile分析

    一. Makefile 配置 1.1. make xxx_config 1.1.1. 笔者实验时是make x210_sd_config a. x210_sd_config是Makefile下的一个目 ...

  4. [BZOJ 2154]Crash的数字表格(莫比乌斯反演+数论分块)

    [BZOJ 2154]Crash的数字表格(莫比乌斯反演+数论分块) 题面 求 \[\sum_{i=1}^{n} \sum_{j=1}^{m} \mathrm{lcm}(i,j)\] 分析 \[\su ...

  5. Scrapy 教程(七)-架构与中间件

    Scrapy 使用 Twisted 这个异步框架来处理网络通信,架构清晰,并且包含了各种中间件接口,可以灵活的完成各种需求. Scrapy 架构 其实之前的教程都有涉及,这里再做个系统介绍 Engin ...

  6. 背包问题: HDU1114Piggy-Bank

    Piggy-Bank Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total ...

  7. HNUSTOJ 1601:名字缩写

    1601: 名字缩写 时间限制: 1 Sec  内存限制: 128 MB 提交: 288  解决: 80 [提交][状态][讨论版] 题目描述 Noname老师有一个班的学生名字要写,但是他太懒了,想 ...

  8. ajax实现异步请求模态登陆

    ajax实现模态登陆 j2ee课程项目实现   Ajax 即"Asynchronous Javascript And XML"(异步 JavaScript 和 XML),是指一种创 ...

  9. SCUT - 216 - 宝华科技树

    https://scut.online/p/216 演员 把这个当成dp算了半天,各种姿势,好吧,就当练习一下树dp. 假如是每个节点的层数之和,按照dp[i][j]为从i点出发获得j科技的最小费用d ...

  10. 利用WebSocket和EventSource实现服务端推送

    可能有很多的同学有用 setInterval 控制 ajax 不断向服务端请求最新数据的经历(轮询)看下面的代码: setInterval(function() { $.get('/get/data- ...