React-Native|实现ListView下拉刷新加载更多
ListView是android中使用频率非常高的控件,在React-Native中也是如此。 使用ListView的步骤,最开始是初始化ListView.DataSource,在构造它时指定更新策略。有两种策略,分别为rowHasChanged和sectionHeaderHasChanged。 另外就是cloneWithRows和cloneWithRowsAndSections,为数据源赋予数据。 经过对ListView的简单研究,我写了一个上拉刷新,加载更多的ListView的例子。源码如下: import ListViewItemDemo from './ListViewItemDemo';
import Toast,{DURATION} from 'react-native-easy-toast';
const URL="http://101.201.78.24/api//activity/list";
let pn=1;
let maxResults=10;
const PageSize="&maxResults="+maxResults;
export default class ListViewDemo extends Component {
constructor(props){
super(props);
this.state={
count:0,result:'',refreshing:true,dataSource:new ListView.DataSource({
rowHasChanged:(r1,r2)=>r1!=r2,}),isFirstIn:true,dataArray:[],};
}
getPromise(url){
var promise=new Promise((resolve,reject)=>{ fetch(url).then(response=> response.json()). then(result=>resolve(result)). catch(error=>reject(error)); }); return promise; } /* 网络加载是异步的,需要结合Promise来进行回调。 fetch(URL)resolve返回的数据是response对象 response.json(),解析一个字符串,构建一个对象或值。相当于JSON.parse() JSON.stringify,从一个对象中解析出字符串 */ componentDidMount(){ this.setState({ refreshing:true,}); let url=URL+"?pn="+pn+PageSize; this.getPromise(url).then(result=> { this.setState({ dataSource: this.state.dataSource.cloneWithRows(result.data.results),refreshing:false,dataArray:result.data.results,}) } ).catch(error=>{ console.log(error) }); } renderRow(item){ return <ListViewItemDemo item={item}/> } renderLine(){ return <View style={styles.line}></View> } onRefresh(){ this.state.dataArray=[]; pn=1; let url=URL+"?pn="+pn+PageSize; this.getPromise(url).then(result=> { this.setState({ dataSource: this.state.dataSource.cloneWithRows(result.data.results),}) } ).catch(error=>{ console.log(error) }); } onEndReached(){ //无论onEndReachedThreshold为多少,首次进来页面,都会调用onEndReached。第一次请求数据时,不加载数据 // this.refs.toast.show("onEndReached0",DURATION.LENGTH_SHORT); if(this.state.isFirstIn){ this.setState({ isFirstIn:false,}); return; } this.refs.toast.show("正在加载更多",DURATION.LENGTH_SHORT); pn++; let url=URL+"?pn="+pn+PageSize; this.getPromise(url).then(result=> { this.setState({ dataSource: this.state.dataSource.cloneWithRows(this.state.dataArray.concat(result.data.results)),isFirstIn:false,dataArray:this.state.dataArray.concat(result.data.results),}) } ).catch(error=>{ console.log(error) }); } render(){ return( <View style={styles.containers}> <ListView dataSource={this.state.dataSource} renderRow={(item)=>this.renderRow(item)} renderSeparator={()=>this.renderLine()} //RefreshControl:给ListView添加下拉刷新 //refreshing,在刷新时是否显示显示器, //onRefresh刷新时执行 refreshControl={ <RefreshControl refreshing={this.state.refreshing} onRefresh={()=>this.onRefresh()} /> } onEndReachedThreshold={100} onEndReached={ ()=>this.onEndReached() } /> {/*Toast在根视图的底部去使用,在视图被渲染时,把toast声明*/} <Toast ref="toast"/> </View> ) } } const styles=StyleSheet.create({ containers: { flex:1,},line:{ backgroundColor:'red',height:0.5,} });
基本的过程就是,进入页面,显示下拉刷新控件,加载第一页的数据。 onEndReached,文档中这样说的,当所有的数据都已经渲染过,并且列表被滚动到距离最底部不足onEndReachedThreshold个像素的距离时调用。 ListView的item的代码如下: const ImageHost='http://101.201.78.24';
export default class ListViewItemDemo extends Component {
constructor(props){
super(props);
}
getActType(){
var temp="";
switch (this.props.item.type){
case 0:
temp="全部";
break;
case 1:
temp="课程";
break;
case 2:
temp="峰会";
break;
case 3:
temp="路演";
break;
case 4:
temp="沙龙";
break;
case 5:
temp="其他";
break;
}
return temp;
}
render(){
return(
<View style={styles.item}>
<View style={styles.leftSection}>
//默认的图片(图片加载不出来显示)
<Image
resizeMode='cover'
style={{width:120,height:80,position:'absolute'}}
source={require('../img/default_activity_list.jpg')}/>
<Image
resizeMode='cover'
style={{width:120,position:'absolute'}}
source={{uri:ImageHost+this.props.item.thumbnail}}/>
</View>
<View style={styles.rightSection}>
<Text style={{fontSize:18}}>{this.props.item.title}</Text>
<View style={{
marginVertical:10,flexDirection:'row',}}>
<Text>{this.props.item.startTime}</Text>
<Text style={{marginLeft:10}}>{this.props.item.city}</Text>
</View>
<View style={{
marginVertical:10,}}>
<Text>{this.getActType()}</Text>
</View>
</View>
</View>)
}
}
const styles=StyleSheet.create({
item: {
flex:1,padding:15,leftSection:{
position:'relative'
},rightSection:{
marginLeft:145,flexDirection:'column',});
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |