React Native (一):基礎(chǔ)
React Native (二):StatusBar 、 NavigationBar 與 TabBar
React Native (三):自定義視圖
React Native (四):加載新聞列表
React Native (五):上下拉刷新加載
React Native (六):加載所有分類與詳情頁(yè)
1.下拉刷新
下拉刷新我們使用 React Native
提供的組件 RefreshControl
空执,去 NewsList.js
的 ListView
添加:
<ListView
style={{flex:1, backgroundColor:'white'}}
dataSource={this.state.dataSource} //設(shè)置數(shù)據(jù)源
renderRow={this.renderRow} //設(shè)置cell
removeClippedSubviews={false}
refreshControl={
<RefreshControl
refreshing={this.state.isRefreshing}
onRefresh={() => this._onRefresh(1)}
tintColor="#999999"
title="加載中..."
titleColor="#999999"
colors={['#ff0000', '#00ff00', '#0000ff']}
progressBackgroundColor="#ffff00"
/>
}
/>
ListView
新加了一個(gè)屬性 removeClippedSubviews
贸营。
我們需要給 state
添加一個(gè) key
: isRefreshing: false
供汛,然后在網(wǎng)絡(luò)請(qǐng)求時(shí)對(duì)它進(jìn)行處理纸镊,(我這里省略了一些代碼被去,要不然太長(zhǎng))
_begainRefresh() {
this.setState({
isRefreshing: true
})
}
_endRefresh() {
this.setState({
isRefreshing: false
})
}
_onRefresh(page) {
if (this.props.dic) {
this._begainRefresh()
if (page == 1) {
this.setState({
page
})
}
let url = ''
fetch(url, {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
})
.then((res) => {
this._endRefresh()
res.json()
.then((json) => {
..... 數(shù)據(jù)的處理
})
.catch((e) => {
})
})
.catch((error) => {
this._endRefresh()
})
}
}
現(xiàn)在運(yùn)行程序就可以盡情地下拉刷新了梯皿。
2.上拉加載
上拉加載我們利用 ListView
的 onEndReached 方法來(lái)進(jìn)行加載新數(shù)據(jù)仇箱,使用 renderFooter 來(lái)進(jìn)行顯示狀態(tài)。
這樣嚴(yán)格的來(lái)說(shuō)并不算上拉加載东羹,只是滑動(dòng)到底部自動(dòng)進(jìn)行加載剂桥。
首先在 ListView
加入:
onEndReached={ this._toEnd }
onEndReachedThreshold={10}
renderFooter={ this._renderFooter }
記得進(jìn)行綁定
this._toEnd = this._toEnd.bind(this)
this._renderFooter = this._renderFooter.bind(this)
實(shí)現(xiàn)
_toEnd() {
if (this.state.isRefreshing) return
this._onRefresh()
}
_renderFooter() {
return (
<View style={{width, height: 40, backgroundColor: '#FFFFFF', alignItems:'center', justifyContent:'center'}}>
<Text>正在加載更多...</Text>
</View>
)
}
現(xiàn)在我們需要對(duì)數(shù)據(jù)進(jìn)行處理,保存請(qǐng)求到的數(shù)據(jù)百姓,再下一頁(yè)數(shù)據(jù)請(qǐng)求到后加入數(shù)組渊额,我們給 state
加入一個(gè) data: []
,然后對(duì)請(qǐng)求到的數(shù)據(jù)進(jìn)行處理:
let list = json.NewsList
let swipers = []
let news = []
if (page == 1) {
for (let index in list) {
let dic = list[index]
index < 4 ? swipers.push(dic) : news.push(dic)
}
news.splice(0, 0, swipers)
} else {
news = list
}
let newData = this.state.data.concat(news)
this.setState({
dataSource: this.state.dataSource.cloneWithRows(newData),
data: newData,
page: this.state.page + (list.length == maxCount ? 1 : 0)
})
這里的 maxCount
是為了方便管理的垒拢,定義為:
const maxCount = 20
請(qǐng)求的 url
改為 :
let url = 'http://api.iapple123.com/newspush/list/index.html?clientid=1114283782&v=1.1&type='
+ this.props.dic.NameEN
+ '&startkey=3001_9223370543834829200_537d522d125e32ae&newkey=&index='
+ page
+ '&size='
+ maxCount
+ '&ime=6271F554-7B2F-45DE-887E-4A336F64DEE6&apptypeid=ZJZYIOS1114283782'
現(xiàn)在可以運(yùn)行看看效果了旬迹。
我們會(huì)發(fā)現(xiàn)一開(kāi)始在加載第一頁(yè)數(shù)據(jù)的時(shí)候 Footer
也顯示了出來(lái),我們需要控制它的顯示與隱藏求类,給 state
加入 showFooter: false
奔垦,在第一頁(yè)數(shù)據(jù)加載完成并且返回的數(shù)組元素個(gè)數(shù)等于 maxCount
則賦值為 true
this.setState({
dataSource: this.state.dataSource.cloneWithRows(newData),
data: newData,
page: this.state.page + (list.length == maxCount ? 1 : 0),
showFooter: this.state.showFooter ? true : (list.length == maxCount ? true : false)
})
_renderFooter() {
if (!this.state.showFooter) {
return null
}
return (
<View style={{width, height: 40, backgroundColor: '#FFFFFF', alignItems:'center', justifyContent:'center'}}>
<Text>正在加載更多</Text>
</View>
)
}
現(xiàn)在 Footer
可以正確的顯示隱藏了,但是我們還需要狀態(tài)來(lái)改變 Footer
顯示的文字尸疆,如果還有更多數(shù)據(jù)椿猎,那我們看見(jiàn) Footer
的時(shí)候它的狀態(tài)顯然是正在加載更多惶岭,如果沒(méi)有更多數(shù)據(jù)了,那我們就顯示 已加載全部 犯眠。
給 state
加入 hasMore: true
按灶,我們先假設(shè)它還有更多
然后在請(qǐng)求到數(shù)據(jù)進(jìn)行處理:
let hasMore = list.length == maxCount ? true : false
this.setState({
dataSource: this.state.dataSource.cloneWithRows(newData),
data: newData,
page: this.state.page + (hasMore ? 1 : 0),
showFooter: this.state.showFooter ? true : (hasMore ? true : false),
hasMore,
})
然后處理 renderFooter
:
_renderFooter() {
if (!this.state.showFooter) {
return null
}
return (
<View style={{width, height: 40, backgroundColor: '#FFFFFF', alignItems:'center', justifyContent:'center'}}>
<Text>{this.state.hasMore ? '正在加載更多...' : '已加載全部'}</Text>
</View>
)
}
我們還需要再 toEnd
的判斷條件加入 hasMore
來(lái)避免顯示沒(méi)有更多數(shù)據(jù)的時(shí)候拉倒底部還會(huì)進(jìn)行請(qǐng)求數(shù)據(jù):
_toEnd() {
if (this.state.isRefreshing || !this.state.hasMore) return
this._onRefresh()
}
到現(xiàn)在上下拉刷新已經(jīng)完成
這個(gè)上拉刷新比較簡(jiǎn)陋,你也可以放 gif圖
或者使用 動(dòng)畫(huà) 來(lái)讓界面變好看點(diǎn)筐咧。