React Native (一):基礎
React Native (二):StatusBar 、 NavigationBar 與 TabBar
React Native (三):自定義視圖
React Native (四):加載新聞列表
React Native (五):上下拉刷新加載
React Native (六):加載所有分類與詳情頁
1.下拉刷新
下拉刷新我們使用 React Native
提供的組件 RefreshControl
,去 NewsList.js
的 ListView
添加:
<ListView
style={{flex:1, backgroundColor:'white'}}
dataSource={this.state.dataSource} //設置數據源
renderRow={this.renderRow} //設置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
新加了一個屬性 removeClippedSubviews
。
我們需要給 state
添加一個 key
: isRefreshing: false
,然后在網絡請求時對它進行處理,(我這里省略了一些代碼,要不然太長)
_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) => {
..... 數據的處理
})
.catch((e) => {
})
})
.catch((error) => {
this._endRefresh()
})
}
}
現在運行程序就可以盡情地下拉刷新了。
2.上拉加載
上拉加載我們利用 ListView
的 onEndReached 方法來進行加載新數據,使用 renderFooter 來進行顯示狀態。
這樣嚴格的來說并不算上拉加載,只是滑動到底部自動進行加載。
首先在 ListView
加入:
onEndReached={ this._toEnd }
onEndReachedThreshold={10}
renderFooter={ this._renderFooter }
記得進行綁定
this._toEnd = this._toEnd.bind(this)
this._renderFooter = this._renderFooter.bind(this)
實現
_toEnd() {
if (this.state.isRefreshing) return
this._onRefresh()
}
_renderFooter() {
return (
<View style={{width, height: 40, backgroundColor: '#FFFFFF', alignItems:'center', justifyContent:'center'}}>
<Text>正在加載更多...</Text>
</View>
)
}
現在我們需要對數據進行處理,保存請求到的數據,再下一頁數據請求到后加入數組,我們給 state
加入一個 data: []
,然后對請求到的數據進行處理:
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
請求的 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'
現在可以運行看看效果了。
我們會發現一開始在加載第一頁數據的時候 Footer
也顯示了出來,我們需要控制它的顯示與隱藏,給 state
加入 showFooter: false
,在第一頁數據加載完成并且返回的數組元素個數等于 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>
)
}
現在 Footer
可以正確的顯示隱藏了,但是我們還需要狀態來改變 Footer
顯示的文字,如果還有更多數據,那我們看見 Footer
的時候它的狀態顯然是正在加載更多,如果沒有更多數據了,那我們就顯示 已加載全部 。
給 state
加入 hasMore: true
,我們先假設它還有更多
然后在請求到數據進行處理:
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
來避免顯示沒有更多數據的時候拉倒底部還會進行請求數據:
_toEnd() {
if (this.state.isRefreshing || !this.state.hasMore) return
this._onRefresh()
}
到現在上下拉刷新已經完成
這個上拉刷新比較簡陋,你也可以放 gif圖
或者使用 動畫 來讓界面變好看點。