1.加载更多功能完善

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. Modal, // 模态
  15. AsyncStorage, // 缓存数据库(数据持久化)
  16. } from 'react-native';
  17.  
  18. // 引入 下拉刷新组件
  19. import {PullList} from 'react-native-pull';
  20. // 导航器
  21. import CustomerComponents, {
  22. Navigator
  23. } from 'react-native-deprecated-custom-components';
  24.  
  25. // 获取屏幕宽高
  26. const {width, height} = Dimensions.get('window');
  27.  
  28. // 引入自定义导航栏组件
  29. import CommunalNavBar from '../main/GDCommunalNavBar';
  30. // 引入 近半小时热门组件
  31. import HalfHourHot from './GDHalfHourHot';
  32. // 引入 搜索页面组件
  33. import Search from './GDSearch';
  34. // 引入 cell
  35. import CommunalHotCell from '../main/GDCommunalHotCell';
  36. // 引入 空白页组件
  37. import NoDataView from '../main/GDNoDataView';
  38.  
  39. // 引入 HTTP封装组件
  40. import HTTPBase from '../http/HTTPBase';
  41.  
  42. export default class GDHome extends Component {
  43.  
  44. // 构造
  45. constructor(props) {
  46. super(props);
  47. // 初始状态
  48. this.state = {
  49. dataSource: new ListView.DataSource({rowHasChanged:(r1, r2) => r1 !== r2}), // 数据源 优化
  50. loaded: false, // 用于判断是否显示空白页
  51. isModal: false, // 用于判断模态的可见性
  52. };
  53. // 全局定义一个空数组用于存储列表数据
  54. this.data = [];
  55. // 绑定
  56. this.loadData = this.loadData.bind(this);
  57. this.loadMore = this.loadMore.bind(this);
  58. }
  59.  
  60. // 加载最新数据网络请求
  61. loadData(resolve) {
  62.  
  63. let params = {"count" : 10 };
  64.  
  65. HTTPBase.get('https://guangdiu.com/api/getlist.php', params)
  66. .then((responseData) => {
  67.           // 情况数据(刷新时)
  68. this.data = [];
  69.  
  70. // 拼接数据
  71. this.data = this.data.concat(responseData.data);
  72.  
  73. // 重新渲染
  74. this.setState({
  75. dataSource: this.state.dataSource.cloneWithRows(this.data),
  76. loaded:true,
  77. });
  78.  
  79. // 关闭刷新动画
  80. if (resolve !== undefined){
  81. setTimeout(() => {
  82. resolve();
  83. }, 1000);
  84. }
  85.  
  86. // 存储数组中最后一个元素的id
  87. let cnlastID = responseData.data[responseData.data.length - 1].id;
  88. AsyncStorage.setItem('cnlastID', cnlastID.toString()); // 只能存储字符或字符串
  89.  
  90. })
  91. .catch((error) => {
  92.  
  93. })
  94. }
  95.  
  96. // 加载更多数据的网络请求
  97. loadMoreData(value) {
  98.  
  99. let params = {
  100. "count" : 10,
  101. "sinceid" : value
  102. };
  103.  
  104. HTTPBase.get('https://guangdiu.com/api/getlist.php', params)
  105. .then((responseData) => {
  106.  
  107. // 拼接数据
  108. this.data = this.data.concat(responseData.data);
  109.  
  110. // 重新渲染
  111. this.setState({
  112. dataSource: this.state.dataSource.cloneWithRows(this.data),
  113. loaded:true,
  114. });
  115.  
  116. // 存储数组中最后一个元素的id
  117. let cnlastID = responseData.data[responseData.data.length - 1].id;
  118. AsyncStorage.setItem('cnlastID', cnlastID.toString()); // 只能存储字符或字符串
  119.  
  120. })
  121. .catch((error) => {
  122.  
  123. })
  124. }
  125.  
  126. // 加载更多数据操作
  127. loadMore() {
  128. // 读取存储的id
  129. AsyncStorage.getItem('cnlastID')
  130. .then((value) => {
  131. // 数据加载操作
  132. this.loadMoreData(value);
  133. })
  134. }
  135.  
  136. // 模态到近半小时热门
  137. pushToHalfHourHot() {
  138. this.setState({
  139. isModal: true
  140. })
  141. }
  142.  
  143. // 跳转到搜索页面
  144. pushToSearch() {
  145. this.props.navigator.push({
  146. component: Search,
  147. })
  148. }
  149.  
  150. // 安卓模态销毁模态
  151. onRequestClose() {
  152. this.setState({
  153. isModal: false
  154. })
  155. }
  156.  
  157. // 关闭模态
  158. closeModal(data) {
  159. this.setState({
  160. isModal:data
  161. })
  162. }
  163.  
  164. // 返回左边按钮
  165. renderLeftItem() {
  166. // 将组件返回出去
  167. return(
  168. <TouchableOpacity
  169. onPress={() => {this.pushToHalfHourHot()}}
  170. >
  171. <Image source={{uri:'hot_icon_20x20'}} style={styles.navbarLeftItemStyle} />
  172. </TouchableOpacity>
  173. );
  174. }
  175.  
  176. // 返回中间按钮
  177. renderTitleItem() {
  178. return(
  179. <TouchableOpacity>
  180. <Image source={{uri:'navtitle_home_down_66x20'}} style={styles.navbarTitleItemStyle} />
  181. </TouchableOpacity>
  182. );
  183. }
  184.  
  185. // 返回右边按钮
  186. renderRightItem() {
  187. return(
  188. <TouchableOpacity
  189. // 跳转搜索页面
  190. onPress={() => {this.pushToSearch()}}
  191. >
  192. <Image source={{uri:'search_icon_20x20'}} style={styles.navbarRightItemStyle} />
  193. </TouchableOpacity>
  194. );
  195. }
  196.  
  197. // ListView尾部
  198. renderFooter() {
  199. return (
  200. <View style={{height: 100}}>
  201. <ActivityIndicator />
  202. </View>
  203. );
  204. }
  205.  
  206. // 根据网络状态决定是否渲染 listView
  207. renderListView() {
  208. if(this.state.loaded === false) {
  209. // 显示空白页
  210. return(
  211. <NoDataView />
  212. );
  213. }else{
  214. return(
  215. <PullList // 将ListView 改为 PullList
  216. // 下拉刷新
  217. onPullRelease={(resolve) => this.loadData(resolve)}
  218. // 数据源 通过判断dataSource是否有变化,来判断是否要重新渲染
  219. dataSource={this.state.dataSource}
  220. renderRow={this.renderRow}
  221. // 隐藏水平线
  222. showsHorizontalScrollIndicator={false}
  223. style={styles.listViewStyle}
  224. initialListSize={5}
  225. // 返回 listView 头部
  226. renderHeader={this.renderHeader}
  227. // 上拉加载更多
  228. onEndReached={this.loadMore}
  229. onEndReachedThreshold={60}
  230. renderFooter={this.renderFooter}
  231. />
  232. );
  233. }
  234. }
  235.  
  236. // 返回每一行cell的样式
  237. renderRow(rowData) {
  238. // 使用cell组件
  239. return(
  240. <CommunalHotCell
  241. image={rowData.image}
  242. title={rowData.title}
  243. />
  244. );
  245. }
  246.  
  247. // 生命周期 组件渲染完成 已经出现在dom文档里
  248. componentDidMount() {
  249. // 请求数据
  250. this.loadData();
  251. }
  252.  
  253. render() {
  254. return (
  255. <View style={styles.container}>
  256. {/* 初始化模态 */}
  257. <Modal
  258. animationType='slide' // 动画 底部弹窗
  259. transparent={false} // 透明度
  260. visible={this.state.isModal} // 可见性
  261. onRequestClose={() => this.onRequestClose()} // 销毁
  262. >
  263. <HalfHourHot removeModal={(data) => this.closeModal(data)} />
  264. </Modal>
  265.  
  266. {/* 导航栏样式 */}
  267. <CommunalNavBar
  268. leftItem = {() => this.renderLeftItem()}
  269. titleItem = {() => this.renderTitleItem()}
  270. rightItem = {() => this.renderRightItem()}
  271. />
  272.  
  273. {/* 根据网络状态决定是否渲染 listView */}
  274. {this.renderListView()}
  275. </View>
  276. );
  277. }
  278. }
  279.  
  280. const styles = StyleSheet.create({
  281. container: {
  282. flex: 1,
  283. alignItems: 'center',
  284. },
  285. navbarLeftItemStyle: {
  286. width:20,
  287. height:20,
  288. marginLeft:15,
  289. },
  290. navbarTitleItemStyle: {
  291. width:66,
  292. height:20,
  293. },
  294. navbarRightItemStyle: {
  295. width:20,
  296. height:20,
  297. marginRight:15,
  298. },
  299.  
  300. listViewStyle: {
  301. width:width,
  302. },
  303. });

核心代码:

  1. // 加载最新数据网络请求
  2. loadData(resolve) {
  3.  
  4. let params = {"count" : 10 };
  5.  
  6. HTTPBase.get('https://guangdiu.com/api/getlist.php', params)
  7. .then((responseData) => {
  8.           // 清空数据(刷新时)
  9. this.data = [];
  10.  
  11. // 拼接数据
  12. this.data = this.data.concat(responseData.data);
  13.  
  14. // 重新渲染
  15. this.setState({
  16. dataSource: this.state.dataSource.cloneWithRows(this.data),
  17. loaded:true,
  18. });
  19.  
  20. // 关闭刷新动画
  21. if (resolve !== undefined){
  22. setTimeout(() => {
  23. resolve();
  24. }, 1000);
  25. }
  26.  
  27. // 存储数组中最后一个元素的id
  28. let cnlastID = responseData.data[responseData.data.length - 1].id;
  29. AsyncStorage.setItem('cnlastID', cnlastID.toString()); // 只能存储字符或字符串
  30.  
  31. })
  32. .catch((error) => {
  33.  
  34. })
  35. }
  36.  
  37. // 加载更多数据的网络请求
  38. loadMoreData(value) {
  39.  
  40. let params = {
  41. "count" : 10,
  42. "sinceid" : value
  43. };
  44.  
  45. HTTPBase.get('https://guangdiu.com/api/getlist.php', params)
  46. .then((responseData) => {
  47.  
  48. // 拼接数据
  49. this.data = this.data.concat(responseData.data);
  50.  
  51. // 重新渲染
  52. this.setState({
  53. dataSource: this.state.dataSource.cloneWithRows(this.data),
  54. loaded:true,
  55. });
  56.  
  57. // 存储数组中最后一个元素的id
  58. let cnlastID = responseData.data[responseData.data.length - 1].id;
  59. AsyncStorage.setItem('cnlastID', cnlastID.toString()); // 只能存储字符或字符串
  60.  
  61. })
  62. .catch((error) => {
  63.  
  64. })
  65. }
  66.  
  67. // 加载更多数据操作
  68. loadMore() {
  69. // 读取存储的id
  70. AsyncStorage.getItem('cnlastID')
  71. .then((value) => {
  72. // 数据加载操作
  73. this.loadMoreData(value);
  74. })
  75. }

2.详情页

(1)Cell 点击实现

我们回到主页这边来实现以下 cell 的点击,需要注意的是对 row 进行绑定操作,不然会找不到当前的 this。

  1. // 绑定
  2. renderRow={this.renderRow.bind(this)}

接着来看下 renderRow 方法实现:

  1. // 返回每一行cell的样式
  2. renderRow(rowData) {
  3. return(
  4. <TouchableOpacity
  5. onPress={() => this.pushToDetail(rowData.id)}
  6. >
  7. <CommunalHotCell
  8. image={rowData.image}
  9. title={rowData.title}
  10. />
  11. </TouchableOpacity>
  12. );
  13. }

再来看下 pushToDetail 方法实现,params意思就是将 url 参数传递到 CommunalDetail 组件:

  1. // 跳转到详情页
  2. pushToDetail(value) {
  3. this.props.navigator.push({
  4. component:CommunalDetail,
  5. params: {
  6. url: 'https://guangdiu.com/api/showdetail.php' + '?' + 'id=' + value
  7. }
  8. })
  9. }

(2)详情页

既然我们已经保存了 id 那么就可以来做详情页了,当我们点击 cell 的时候,需要跳转到对应的 详情页 。

先来看详情页的实现:

GDCommunalDetail.js

  1. /**
  2. * 详情页
  3. */
  4. import React, { Component, PropTypes } from 'react';
  5. import {
  6. StyleSheet,
  7. WebView,
  8. View,
  9. Text,
  10. TouchableOpacity,
  11. DeviceEventEmitter,
  12. } from 'react-native';
  13.  
  14. // 导航器
  15. import CustomerComponents, {
  16. Navigator
  17. } from 'react-native-deprecated-custom-components';
  18.  
  19. // 引入自定义导航栏组件
  20. import CommunalNavBar from './GDCommunalNavBar';
  21.  
  22. export default class GDCommunalDetail extends Component {
  23.  
  24. // 创建属性,便于外部传值使用
  25. static propTypes = {
  26. uri:PropTypes.string,
  27. };
  28.  
  29. // 返回
  30. pop() {
  31. this.props.navigator.pop();
  32. }
  33.  
  34. // 返回左边按钮
  35. renderLeftItem() {
  36. return(
  37. <TouchableOpacity
  38. onPress={() => {this.pop()}}
  39. >
  40. <Text>返回</Text>
  41. </TouchableOpacity>
  42. );
  43. }
  44.  
  45. componentWillMount() {
  46. // 向GDMain.js 发送通知 隐藏tabBar
  47. DeviceEventEmitter.emit('isHiddenTabBar', true);
  48. }
  49.  
  50. componentWillUnmount() {
  51. // 向GDMain.js 发送通知 显示tabBar
  52. DeviceEventEmitter.emit('isHiddenTabBar', false);
  53. }
  54.  
  55. render() {
  56. return(
  57. <View style={styles.container}>
  58. {/* 导航栏 */}
  59. <CommunalNavBar
  60. leftItem = {() => this.renderLeftItem()}
  61. />
  62.  
  63. {/* 初始化WebView */}
  64. <WebView
  65. style={styles.webViewStyle}
  66. source={{uri:this.props.url, method: 'GET' }}
  67. javaScriptEnabled={true}
  68. domStorageEnabled={true}
  69. scalesPageToFit={false}
  70. />
  71. </View>
  72. );
  73. }
  74. }
  75.  
  76. const styles = StyleSheet.create({
  77. container: {
  78. flex:1
  79. },
  80.  
  81. webViewStyle: {
  82. flex: 1
  83. }
  84. });

效果图

3. 调用

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. Modal, // 模态
  15. AsyncStorage, // 缓存数据库(数据持久化)
  16. } from 'react-native';
  17.  
  18. // 引入 下拉刷新组件
  19. import {PullList} from 'react-native-pull';
  20. // 导航器
  21. import CustomerComponents, {
  22. Navigator
  23. } from 'react-native-deprecated-custom-components';
  24.  
  25. // 获取屏幕宽高
  26. const {width, height} = Dimensions.get('window');
  27.  
  28. // 引入自定义导航栏组件
  29. import CommunalNavBar from '../main/GDCommunalNavBar';
  30. // 引入 近半小时热门组件
  31. import HalfHourHot from './GDHalfHourHot';
  32. // 引入 搜索页面组件
  33. import Search from './GDSearch';
  34. // 引入 cell
  35. import CommunalHotCell from '../main/GDCommunalHotCell';
  36. // 引入 详情页 组件
  37. import CommunalDetail from '../main/GDCommunalDetail';
  38. // 引入 空白页组件
  39. import NoDataView from '../main/GDNoDataView';
  40.  
  41. // 引入 HTTP封装组件
  42. import HTTPBase from '../http/HTTPBase';
  43.  
  44. export default class GDHome extends Component {
  45.  
  46. // 构造
  47. constructor(props) {
  48. super(props);
  49. // 初始状态
  50. this.state = {
  51. dataSource: new ListView.DataSource({rowHasChanged:(r1, r2) => r1 !== r2}), // 数据源 优化
  52. loaded: false, // 用于判断是否显示空白页
  53. isModal: false, // 用于判断模态的可见性
  54. };
  55. // 全局定义一个空数组用于存储列表数据
  56. this.data = [];
  57. // 绑定
  58. this.loadData = this.loadData.bind(this);
  59. this.loadMore = this.loadMore.bind(this);
  60. }
  61.  
  62. // 加载最新数据网络请求
  63. loadData(resolve) {
  64.  
  65. let params = {"count" : 10 };
  66.  
  67. HTTPBase.get('https://guangdiu.com/api/getlist.php', params)
  68. .then((responseData) => {
  69.           // 清空数据
  70. this.data = [];
  71.  
  72. // 拼接数据
  73. this.data = this.data.concat(responseData.data);
  74.  
  75. // 重新渲染
  76. this.setState({
  77. dataSource: this.state.dataSource.cloneWithRows(this.data),
  78. loaded:true,
  79. });
  80.  
  81. // 关闭刷新动画
  82. if (resolve !== undefined){
  83. setTimeout(() => {
  84. resolve();
  85. }, 1000);
  86. }
  87.  
  88. // 存储数组中最后一个元素的id
  89. let cnlastID = responseData.data[responseData.data.length - 1].id;
  90. AsyncStorage.setItem('cnlastID', cnlastID.toString()); // 只能存储字符或字符串
  91.  
  92. })
  93. .catch((error) => {
  94.  
  95. })
  96. }
  97.  
  98. // 加载更多数据的网络请求
  99. loadMoreData(value) {
  100.  
  101. let params = {
  102. "count" : 10,
  103. "sinceid" : value
  104. };
  105.  
  106. HTTPBase.get('https://guangdiu.com/api/getlist.php', params)
  107. .then((responseData) => {
  108.  
  109. // 拼接数据
  110. this.data = this.data.concat(responseData.data);
  111.  
  112. // 重新渲染
  113. this.setState({
  114. dataSource: this.state.dataSource.cloneWithRows(this.data),
  115. loaded:true,
  116. });
  117.  
  118. // 存储数组中最后一个元素的id
  119. let cnlastID = responseData.data[responseData.data.length - 1].id;
  120. AsyncStorage.setItem('cnlastID', cnlastID.toString()); // 只能存储字符或字符串
  121.  
  122. })
  123. .catch((error) => {
  124.  
  125. })
  126. }
  127.  
  128. // 加载更多数据操作
  129. loadMore() {
  130. // 读取存储的id
  131. AsyncStorage.getItem('cnlastID')
  132. .then((value) => {
  133. // 数据加载操作
  134. this.loadMoreData(value);
  135. })
  136. }
  137.  
  138. // 模态到近半小时热门
  139. pushToHalfHourHot() {
  140. this.setState({
  141. isModal: true
  142. })
  143. }
  144.  
  145. // 跳转到搜索页面
  146. pushToSearch() {
  147. this.props.navigator.push({
  148. component: Search,
  149. })
  150. }
  151.  
  152. // 安卓模态销毁模态
  153. onRequestClose() {
  154. this.setState({
  155. isModal: false
  156. })
  157. }
  158.  
  159. // 关闭模态
  160. closeModal(data) {
  161. this.setState({
  162. isModal:data
  163. })
  164. }
  165.  
  166. // 返回左边按钮
  167. renderLeftItem() {
  168. // 将组件返回出去
  169. return(
  170. <TouchableOpacity
  171. onPress={() => {this.pushToHalfHourHot()}}
  172. >
  173. <Image source={{uri:'hot_icon_20x20'}} style={styles.navbarLeftItemStyle} />
  174. </TouchableOpacity>
  175. );
  176. }
  177.  
  178. // 返回中间按钮
  179. renderTitleItem() {
  180. return(
  181. <TouchableOpacity>
  182. <Image source={{uri:'navtitle_home_down_66x20'}} style={styles.navbarTitleItemStyle} />
  183. </TouchableOpacity>
  184. );
  185. }
  186.  
  187. // 返回右边按钮
  188. renderRightItem() {
  189. return(
  190. <TouchableOpacity
  191. // 跳转搜索页面
  192. onPress={() => {this.pushToSearch()}}
  193. >
  194. <Image source={{uri:'search_icon_20x20'}} style={styles.navbarRightItemStyle} />
  195. </TouchableOpacity>
  196. );
  197. }
  198.  
  199. // ListView尾部
  200. renderFooter() {
  201. return (
  202. <View style={{height: 100}}>
  203. <ActivityIndicator />
  204. </View>
  205. );
  206. }
  207.  
  208. // 根据网络状态决定是否渲染 listView
  209. renderListView() {
  210. if(this.state.loaded === false) {
  211. // 显示空白页
  212. return(
  213. <NoDataView />
  214. );
  215. }else{
  216. return(
  217. <PullList // 将ListView 改为 PullList
  218. // 下拉刷新
  219. onPullRelease={(resolve) => this.loadData(resolve)}
  220. // 数据源 通过判断dataSource是否有变化,来判断是否要重新渲染
  221. dataSource={this.state.dataSource}
  222. renderRow={this.renderRow.bind(this)}
  223. // 隐藏水平线
  224. showsHorizontalScrollIndicator={false}
  225. style={styles.listViewStyle}
  226. initialListSize={5}
  227. // 返回 listView 头部
  228. renderHeader={this.renderHeader}
  229. // 上拉加载更多
  230. onEndReached={this.loadMore}
  231. onEndReachedThreshold={60}
  232. renderFooter={this.renderFooter}
  233. />
  234. );
  235. }
  236. }
  237.  
  238. // 通过id 跳转详情页
  239. pushToDetail(value) {
  240. this.props.navigator.push({
  241. component:CommunalDetail,
  242. params: {
  243. url: 'https://guangdiu.com/api/showdetail.php' + '?' + 'id=' + value
  244. }
  245. })
  246. }
  247.  
  248. // 返回每一行cell的样式
  249. renderRow(rowData) {
  250. // 使用cell组件
  251. return(
  252. <TouchableOpacity
  253. // 给每一个cell添加点击事件
  254. onPress={() => this.pushToDetail(rowData.id)}
  255. >
  256. <CommunalHotCell
  257. image={rowData.image}
  258. title={rowData.title}
  259. />
  260. </TouchableOpacity>
  261. );
  262. }
  263.  
  264. // 生命周期 组件渲染完成 已经出现在dom文档里
  265. componentDidMount() {
  266. // 请求数据
  267. this.loadData();
  268. }
  269.  
  270. render() {
  271. return (
  272. <View style={styles.container}>
  273. {/* 初始化模态 */}
  274. <Modal
  275. animationType='slide' // 动画 底部弹窗
  276. transparent={false} // 透明度
  277. visible={this.state.isModal} // 可见性
  278. onRequestClose={() => this.onRequestClose()} // 销毁
  279. >
  280. <Navigator
  281. initialRoute={{
  282. name:'halfHourHot',
  283. component:HalfHourHot
  284. }}
  285.  
  286. renderScene={(route, navigator) => {
  287. let Component = route.component;
  288. return <Component
  289. removeModal={(data) => this.closeModal(data)}
  290. {...route.params}
  291. navigator={navigator} />
  292. }} />
  293. </Modal>
  294.  
  295. {/* 导航栏样式 */}
  296. <CommunalNavBar
  297. leftItem = {() => this.renderLeftItem()}
  298. titleItem = {() => this.renderTitleItem()}
  299. rightItem = {() => this.renderRightItem()}
  300. />
  301.  
  302. {/* 根据网络状态决定是否渲染 listView */}
  303. {this.renderListView()}
  304. </View>
  305. );
  306. }
  307. }
  308.  
  309. const styles = StyleSheet.create({
  310. container: {
  311. flex: 1,
  312. alignItems: 'center',
  313. },
  314. navbarLeftItemStyle: {
  315. width:20,
  316. height:20,
  317. marginLeft:15,
  318. },
  319. navbarTitleItemStyle: {
  320. width:66,
  321. height:20,
  322. },
  323. navbarRightItemStyle: {
  324. width:20,
  325. height:20,
  326. marginRight:15,
  327. },
  328.  
  329. listViewStyle: {
  330. width:width,
  331. },
  332. });

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 CommunalDetail from '../main/GDCommunalDetail';
  25. // 引入 空白页组件
  26. import NoDataView from '../main/GDNoDataView';
  27. // 引入 下拉刷新组件
  28. import {PullList} from 'react-native-pull';
  29.  
  30. // 引入 HTTP封装组件
  31. import HTTPBase from '../http/HTTPBase';
  32.  
  33. export default class GDHalfHourHot extends Component {
  34.  
  35. // 构造
  36. constructor(props) {
  37. super(props);
  38. // 初始状态
  39. this.state = {
  40. dataSource: new ListView.DataSource({rowHasChanged:(r1, r2) => r1 !== r2}), // 数据源 优化
  41. loaded: false, // 用于判断是否显示空白页
  42. };
  43. // 绑定
  44. this.fetchData = this.fetchData.bind(this);
  45. }
  46.  
  47. // 提供参数出去,便于外部调用
  48. static defaultProps = {
  49. removeModal:{}
  50. }
  51.  
  52. // 网络请求
  53. fetchData(resolve) {
  54.  
  55. HTTPBase.get('http://guangdiu.com/api/gethots.php')
  56. .then((responseData) => { // 处理数据
  57. // 修改dataSource的值
  58. this.setState({
  59. dataSource: this.state.dataSource.cloneWithRows(responseData.data),
  60. loaded:true,
  61. });
  62. // 关闭下拉刷新动画
  63. if (resolve !== undefined){
  64. // 使用定时器 延时关闭动画
  65. setTimeout(() => {
  66. resolve(); // 关闭动画
  67. }, 1000);
  68. }
  69. })
  70. .catch((error) => {
  71.  
  72. })
  73. }
  74.  
  75. popToHome(data) {
  76. // 向外部传值
  77. this.props.removeModal(data);
  78. }
  79.  
  80. // 返回中间按钮
  81. renderTitleItem() {
  82. return(
  83. <Text style={styles.navbarTitleItemStyle}>近半小时热门</Text>
  84. );
  85. }
  86.  
  87. // 返回右边按钮
  88. renderRightItem() {
  89. return(
  90. <TouchableOpacity
  91. onPress={() => {this.popToHome(false)}}
  92. >
  93. <Text style={styles.navbarRightItemStyle}>关闭</Text>
  94. </TouchableOpacity>
  95. );
  96. }
  97.  
  98. // 根据网络状态决定是否渲染 listView
  99. renderListView() {
  100. if(this.state.loaded === false) {
  101. // 显示空白页
  102. return(
  103. <NoDataView />
  104. );
  105. }else{
  106. return(
  107. <PullList // 将ListView 改为 PullList
  108. // 下拉刷新
  109. onPullRelease={(resolve) => this.fetchData(resolve)}
  110. // 数据源 通过判断dataSource是否有变化,来判断是否要重新渲染
  111. dataSource={this.state.dataSource}
  112. renderRow={this.renderRow.bind(this)}
  113. // 隐藏水平线
  114. showsHorizontalScrollIndicator={false}
  115. style={styles.listViewStyle}
  116. initialListSize={5}
  117. // 返回 listView 头部
  118. renderHeader={this.renderHeader}
  119. />
  120. );
  121. }
  122. }
  123.  
  124. // 返回 listView 头部
  125. renderHeader() {
  126. return(
  127. <View style={styles.headerPromptStyle}>
  128. <Text>根据每条折扣的点击进行统计,每5分钟更新一次</Text>
  129. </View>
  130. );
  131. }
  132.  
  133. // 通过id 跳转详情页
  134. pushToDetail(value) {
  135. this.props.navigator.push({
  136. component:CommunalDetail,
  137. params: {
  138. url: 'http://guangdiu.com/api/showdetail.php' + '?' + 'id=' + value
  139. }
  140. })
  141. }
  142.  
  143. // 返回每一行cell的样式
  144. renderRow(rowData) {
  145. // 使用cell组件
  146. return(
  147. <TouchableOpacity
  148. // 给每一个cell添加点击事件
  149. onPress={() => this.pushToDetail(rowData.id)}
  150. >
  151. <CommunalHotCell
  152. image={rowData.image}
  153. title={rowData.title}
  154. />
  155. </TouchableOpacity>
  156. );
  157. }
  158.  
  159. componentWillMount() {
  160. // 向GDMain.js 发送通知 隐藏tabBar
  161. DeviceEventEmitter.emit('isHiddenTabBar', true);
  162. }
  163.  
  164. componentWillUnmount() {
  165. // 向GDMain.js 发送通知 显示tabBar
  166. DeviceEventEmitter.emit('isHiddenTabBar', false);
  167. }
  168.  
  169. // 生命周期 组件渲染完成 已经出现在dom文档里
  170. componentDidMount() {
  171. // 请求数据
  172. this.fetchData();
  173. }
  174.  
  175. render() {
  176. return (
  177. <View style={styles.container}>
  178. {/* 导航栏样式 */}
  179. <CommunalNavBar
  180. titleItem = {() => this.renderTitleItem()}
  181. rightItem = {() => this.renderRightItem()}
  182. />
  183.  
  184. {/* 根据网络状态决定是否渲染 listView */}
  185. {this.renderListView()}
  186. </View>
  187. );
  188. }
  189. }
  190.  
  191. const styles = StyleSheet.create({
  192. container: {
  193. flex:1,
  194. alignItems: 'center',
  195. },
  196.  
  197. navbarTitleItemStyle: {
  198. fontSize:17,
  199. color:'black',
  200. marginLeft:50
  201. },
  202. navbarRightItemStyle: {
  203. fontSize:17,
  204. color:'rgba(123,178,114,1.0)',
  205. marginRight:15
  206. },
  207.  
  208. headerPromptStyle: {
  209. height:44,
  210. width:width,
  211. backgroundColor:'rgba(239,239,239,0.5)',
  212. justifyContent:'center',
  213. alignItems:'center'
  214. },
  215.  
  216. listViewStyle: {
  217. width:width,
  218. },
  219. });

.

React-Native 之 GD (十一)加载更多功能完善 及 跳转详情页的更多相关文章

  1. Android 上拉加载更多功能

    前几天看了github上面的例子,参照它的实现,自己又稍微改了一点,往项目里面增加了一个上拉加载更多功能.具体的实现如下: 首先要重写ListView: import android.content. ...

  2. jQuery+php+Ajax文章列表点击加载更多功能

    jQuery+php+Ajax实现的一个简单实用的文章列表点击加载更多功能,点击加载更多按钮,文章列表加载更多数据,加载中有loading动画效果. js部分: <script type=&qu ...

  3. 分页插件思想:pc加载更多功能和移动端下拉刷新加载数据

    感觉一个人玩lol也没意思了,玩会手机,看到这个下拉刷新功能就写了这个demo! 这个demo写的比较随意,咱不能当做插件使用,基本思想是没问题的,要用就自己封装吧! 直接上代码分析下吧! 布局: & ...

  4. iOS开发UI篇—在UItableview中实现加载更多功能

    一.实现效果 点击加载更多按钮,出现一个加载图示,三秒钟后添加两条新的数据.                      二.实现代码和说明 当在页面(视图部分)点击加载更多按钮的时候,主页面(主控制器 ...

  5. Android 开发 上拉加载更多功能实现

    实现思维 开始之前先废话几句,Android系统没有提供上拉加载的控件,只提供了下拉刷新的SwipeRefreshLayout控件.这个控件我们就不废话,无法实现上拉刷新的功能.现在我们说说上拉加载更 ...

  6. 移动端web页面上滑加载更多功能

    背景介绍: 开发企业微信的一个应用,实现在企业微信中调用自己程序页面,页面加载多模块数据,向下滑加载更多,等等等等,一波三折 然后很早就成功了是这样实现的: html: <div id=&quo ...

  7. jQuery+Asp.net 实现简单的下拉加载更多功能

    原来做过的商城项目现在需要增加下拉加载的功能,简单的实现了一下.大概可以整理一下思路跟代码. 把需要下拉加载的内容进行转为JSON处理存在当前页面: <script type="tex ...

  8. Flutter移动电商实战 --(20)首页上拉加载更多功能的制作

    这节课学习一下上拉加载效果,其实现在上拉加载的插件有很多,但是还没有一个插件可以说完全一枝独秀,我也找了一个插件,这个插件的优点就是服务比较好,作者能及时回答大家的问题.我觉的选插件也是选人,人对了, ...

  9. React Native封装Toast与加载Loading组件

    React Native开发封装Toast与加载Loading组件 在App开发中,我们避免不了使用的两个组件,一个Toast,一个网络加载Loading,在RN开发中,也是一样,React Nati ...

随机推荐

  1. 树形dp相关

    前言 1:与树或图的生成树相关的动态规划. 2:以每棵子树为子结构,在父亲节点合并,注意树具有天然的子结构.这是很优美的很利于dp的. 3:巧妙利用Bfs或Dfs序,可以优化问题,或得到好的解决方法. ...

  2. mysql 大数据分页优化

    一.mysql大数据量使用limit分页,随着页码的增大,查询效率越低下. 1.   直接用limit start, count分页语句, 也是我程序中用的方法: select * from prod ...

  3. 并发编程时守护进程在pycharm与python shell中的运行结果不同

    原代码如下 from multiprocessing import Process import time import random def task(name): print('%s is run ...

  4. HNUSTOJ-1690 千纸鹤

    1690: 千纸鹤 时间限制: 1 Sec  内存限制: 128 MB提交: 992  解决: 296[提交][状态][讨论版] 题目描述  圣诞节快到了,校园里到处弥漫着粉红色的气息.又是一个情侣秀 ...

  5. 模板 - SG函数

    https://scut.online/p/93 每次取走的石子是b的幂次.打表暴力发现规律. #include <bits/stdc++.h> using namespace std; ...

  6. Maven快速安装配置

    环境:windows7_x86  maven3.3.3   maven是管理项目的常用工具,不用安装,直接配置即可.在配置maven前,需要先安装JDK.   1,安装JDK(注意此版本的Maven要 ...

  7. jmeter性能测试抛除工具用命令测试的方法

    1.我们有时会遇到那种图片或文件大的传输数据,容易将jmeter测试工具卡死,这个时候就需要抛除测试工具,直接用命令进行测试(window和linux都适用) 2.首先在jmeter工具上把性能测试脚 ...

  8. sqlserver 创建 aspstate的方法

    找到路径 C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727 不同版本找不同版本的路径 在命令行执行命令 aspnet_regsql.exe -ssadd -s ...

  9. SpringBoot自定义配置步骤

    1. 在yml中填写自定义配置 ly: sms: accessKeyId: # 短信配置 accessKeySecret: signName: xx商城 # 签名名称 verifyCodeTempla ...

  10. unittest生成报告

    # html报告文件路径    report_abspath = os.path.join(report_path, "result.html")    fp = open(rep ...