在手机应用上,上拉加载更多的功能是必不可少的。同时,在实际使用的时候,当下拉加载,数据仍未返回时,用户多次重复进行下拉加载的操作,为了不产生额外的垃圾数据,我们需要进行判断。同时为了更好的用户体验,增加数据缓存功能。
list.js文件
/**
* Sample React Native App
* https://github.com/facebook/react-native
* @flow
*/
import React, {Component} from 'react';
import {
Platform,
StyleSheet,
Text,
View,
ListView,
TouchableOpacity,
Image,
ActivityIndicator,
} from 'react-native';
import Icon from 'react-native-vector-icons/Ionicons';
import Dimensions from 'Dimensions';
const {width, height} = Dimensions.get('window');
import config from '../common/config';
import request from '../common/request';
// Mockjs 解析随机的文字
import Mock from 'mockjs';
let cachedResult = {
nexPage: 1,
item: [],
total: 0,
}
export default class list extends Component {
constructor(props) {
super(props);
this.state = {
dataSource: new ListView.DataSource({
rowHasChanged: (r1, r2)=>r1 !== r2,
}),
isLoadingTail: false //没有加载数据
}
}
//即将显示
componentWillMount() {
//加载本地数据
// this.dsfetchData();
}
componentDidMount() {
//加载网络数据
this._fetchData(1);
}
_fetchData(page) {
this.setState({
isLoadingTail: true
});
//发送网络请求
request.get(config.api.base + config.api.list, {
accessToken: '001',
a: 'list',
c: 'data',
type: 29,
page: page
}).then(
(data) => {
//将服务器得到的数据缓存进来
let items = cachedResult.item.concat(data.list);//把缓存的数据进行拼接
cachedResult.item = items;
cachedResult.total = items.total;
console.log(items);
console.log('总数据是:' + cachedResult.total);
console.log('当前到了第:' + cachedResult.item.length + '个!');
this.setState({
dataSource: this.state.dataSource.cloneWithRows(
cachedResult.item
),
isLoadingTail: false
});
}
).catch(
(error) => {
console.log('err' + error);
}
)
}
// dsfetchData() {
// let result = Mock.mock({
// "data|20": [
// {
// "_id": "@ID",
// "thumb": "@IMG(1024x700,@COLOR(),\'\u56fe\u7247\u4e0a\u7684\u6587\u5b57\')",
// "title": "@cparagraph(1, 3)",
// "video": "\'http:\/\/v.youku.com\/v_show\/id_XMzY5ODY5MDI3Ng==.html?spm=a2h1n.8251846.0.0\'"
// }
// ],
// "success": true
// })
// this.setState({
// dataSource: this.state.dataSource.cloneWithRows(result.data)
// })
// }
render() {
return (
<View style={styles.container}>
{/*导航条*/}
<View style={styles.header}>
<Text style={styles.headerText}>
视频列表
</Text>
</View>
{/*列表页面*/}
<ListView
dataSource={this.state.dataSource}
renderRow={this._renderRow}
style={styles.listView}
onEndReached={this._fetchMoreData}//滚到底部加载更多数据
onEndReachedThreshold={20} //距离底部还有多远触发
renderFooter={this._renderFooter}
/>
</View>
);
}
//自定义Footer视图
_renderFooter = ()=> {
if (!this._hasMore() && cachedResult.total !==0) {
return (
<View style={styles.loadingMore}>
<Text style={styles.loadingText}>没有更多数据啦...</Text>
</View>
)
}
// if(!this.state.isLoadingTail){
// return(<View></View>)
// }
//显示一朵小菊花
return(
<ActivityIndicator style={styles.loadingMore}></ActivityIndicator>
)
}
//思路:有多种解决方案
//1.发送请求 2.保存请求参数 3.对比参数
//刷新请求 2.保存request = refresh 3.对比 refresh==保存request 状态机中的page值
//状态机 loading = refresh
//上拉加载更多数据
_fetchMoreData = ()=> {
//判断是否有更多数据或者是否在请求中
if (!this._hasMore || this.isLoadingTail) {
return
}
let page = cachedResult.nexPage;
//去服务器去加载更多数据
this._fetchData(page);
}
//判断是否还有更多数据
_hasMore() {
return cachedResult.item.length !== cachedResult.total;
}
//下划线代表内部类自己用的函数,属于规范
_renderRow = (rowData)=> {
return (
<TouchableOpacity>
{/*整个Cell*/}
<View style={styles.cellStyle}>
{/*标题文字*/}
<Text style={styles.title}>{rowData.text}</Text>
<Image style={styles.thumb} source={{uri: rowData.profile_image}}>
</Image>
<Icon name="ios-play"
size={30}
style={styles.play}
/>
{/*点赞&评论*/}
<View style={styles.cellFooter}>
{/*点赞*/}
<View style={styles.footerBox}>
<Icon name="ios-heart-outline"
size={30}
style={styles.boxIcon}
/>
{/*点赞文字*/}
<Text style={styles.boxText}>点赞</Text>
</View>
{/*评论*/}
<View style={styles.footerBox}>
<Icon name="ios-chatbubbles-outline"
size={30}
style={styles.boxIcon}
/>
{/*点赞文字*/}
<Text style={styles.boxText}>评论</Text>
</View>
</View>
</View>
</TouchableOpacity>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#F5FCFF',
},
header: {
// marginTop:Platform.OS == 'ios'?20:0,
paddingTop: 25,
paddingBottom: 15,
backgroundColor: '#dddddd',
borderBottomWidth: 0.5,
borderBottomColor: 'black',
},
headerText: {
fontWeight: '600',
textAlign: 'center',
fontSize: 16,
},
listView: {},
cellStyle: {
width: width,
marginTop: 10,
backgroundColor: 'white',
},
title: {
padding: 10,
color: 'black',
fontSize: 18
},
thumb: {
width: width,
height: width * 0.56,
resizeMode: 'cover'
},
play: {
position: 'absolute',
bottom: 100,
right: 14,
width: 46,
height: 46,
paddingTop: 8,
paddingLeft: 18,
backgroundColor: 'transparent',
borderColor: 'black',
borderWidth: 0.5,
borderRadius: 23,
},
cellFooter: {
flexDirection: 'row',
justifyContent: 'space-between',
backgroundColor: '#dddddd',
},
footerBox: {
padding: 10,
flexDirection: 'row',
backgroundColor: 'white',
flex: 1,
marginLeft: 1,
justifyContent: 'center',
},
boxIcon: {
fontSize: 22,
color: '#333',
},
boxText: {
fontSize: 18,
color: '#333',
paddingLeft: 12,
marginTop: 2
},
loadingMore:{
marginVertical:20
},
loadingText:{
fontSize:18,
color:'#777',
textAlign:'center'
}
});
当然,我们使用的是抓包抓到的接口,接口当中没有给出我们需要的total字段,在实际项目中,我们需要跟后台去协调,并给我们数据总量