之前寫iOS時赘艳,有這非常好用的下拉刷新和上拉加載的組件如MJReferesh這樣優(yōu)秀的組件酌毡,但是最近寫ReactNative時,一直沒發(fā)現(xiàn)非常如意的第三方下拉刷新的組件蕾管,所以便自己寫了一個簡單好用的刷新組件react-native-swRefresh枷踏,支持scrollView,ListView,支持自定義。支持iOS和Android
更新Android支持 實(shí)現(xiàn)方式不一樣 所以Android體驗(yàn)可能稍微有點(diǎn)不同
新增beginRefresh()和endRefresh()方法來手動調(diào)用下拉刷新和結(jié)束下拉刷新 類iOS中的MJRefrsh
新增endLoadMore() 結(jié)束上拉加載 代替end()回調(diào) 同樣可以傳入bool參數(shù)代表這次結(jié)束是否進(jìn)入已無更多狀態(tài)掰曾。
因?yàn)閯偨佑|旭蠕,所以也寫不出非常優(yōu)美的代碼,改著改著就有點(diǎn)冗余了,有空就優(yōu)化下旷坦,但是個人覺的應(yīng)該是很好用的組件掏熬,這篇文章主要是介紹其如何使用:
-
安裝:
npm install react-native-swRefresh
-
使用:
- 引入
//根據(jù)需要引入
import {
SwRefreshScrollView, //支持下拉刷新的ScrollView
SwRefreshListView, //支持下拉刷新和上拉加載的ListView
RefreshStatus, //刷新狀態(tài) 用于自定義下拉刷新視圖時使用
LoadMoreStatus //上拉加載狀態(tài) 用于自定義上拉加載視圖時使用
} from 'react-native-swRefresh'
具體屬性和方法 github上有介紹
- 簡單使用(兩個組件下拉刷新的使用方法是一樣的,本文以SwRefreshListView為例)
_page = 0
_dataSource = new ListView.DataSource({rowHasChanged:(row1,row2)=>row1 !== row2})
// 構(gòu)造
constructor(props) {
super(props);
// 初始狀態(tài)
this.state = {
dataSource:this._dataSource.cloneWithRows([0,1,2,3,4,5,6,7,8,9,0])
};
}
render(){
return this._renderListView() // ListView Demo
}
_renderListView(){
return(
<SwRefreshListView
dataSource={this.state.dataSource}
ref="listView"
renderRow={this._renderRow.bind(this)}
onRefresh={this._onListRefersh.bind(this)}//設(shè)置下拉刷新的方法 傳遞參數(shù)end函數(shù) 當(dāng)刷新操作結(jié)束時
onLoadMore={this._onLoadMore.bind(this)} //設(shè)置上拉加載執(zhí)行的方法 傳遞參數(shù)end函數(shù) 當(dāng)刷新操作結(jié)束時 end函數(shù)可接受一個bool值參數(shù)表示刷新結(jié)束后是否已經(jīng)無更多數(shù)據(jù)了秒梅。
//isShowLoadMore={false} //可以通過state控制是否顯示上拉加載組件旗芬,可用于數(shù)據(jù)不足一屏或者要求數(shù)據(jù)全部加載完畢時不顯示上拉加載控件
customRefreshView={(refresStatus,offsetY)=>{
return (<Text>{'狀態(tài):'+refresStatus+','+offsetY}</Text>)
}} //自定義下拉刷新視圖參數(shù),refresStatus是上面引入的RefreshStatus類型捆蜀,對應(yīng)刷新狀態(tài)各個狀態(tài)疮丛。offsetY對應(yīng)下拉的偏移量,可用于定制動畫。自定義視圖必須通過customRefreshViewHeight指定高度
customRefreshViewHeight={100} //自定義刷新視圖時必須指定高度
/>)
}
/**
* 模擬刷新
* @param end
* @private
*/
_onListRefersh(end){
let timer = setTimeout(()=>{
console.log('刷新成功')
clearTimeout(timer)
this._page=0
let data = []
for (let i = 0;i<10;i++){
data.push(i)
}
this.setState({
dataSource:this._dataSource.cloneWithRows(data)
})
//推薦以下寫法 用戶體驗(yàn)更好
if(已加載全部數(shù)據(jù)){
//如果此時刷新的數(shù)據(jù)就已經(jīng)是全部數(shù)據(jù)了漱办,不管怎樣都應(yīng)該將上拉加載組件設(shè)置為沒有更多數(shù)據(jù)了的狀態(tài) 或者通過isShowLoadMore控制其隱藏
this.refs.listView.setNoMoreData() //設(shè)置為沒有更多數(shù)據(jù)了的狀態(tài)
}else{
//這里調(diào)用resetStatus來重置上拉加載的狀態(tài) 因?yàn)榇饲翱缮侠虞d組件的狀態(tài)可能已經(jīng)是無更多數(shù)據(jù)了 所以進(jìn)行狀態(tài)重置 亦可以通 過state控制isShowLoadMore來控制顯示上拉加載視圖
this.refs.listView.resetStatus() //重置上拉加載的狀態(tài)
}
//如果不這么寫 上拉一次后 上拉組件也會獲知正確的狀態(tài)
end()//刷新成功后需要調(diào)用end結(jié)束刷新 不管成功或者失敗都應(yīng)該結(jié)束
/ / this.refs.listView.endRefresh() //新增方法 結(jié)束刷新 建議使用end() 这刷。當(dāng)然這個可以在任何地方使用
},1500)
}
/**
* 模擬加載更多
* @param end
* @private
*/
_onLoadMore(end){
let timer = setTimeout(()=>{
clearTimeout(timer)
this._page++
let data = []
for (let i = 0;i<(this._page+1)*10;i++){
data.push(i)
}
this.setState({
dataSource:this._dataSource.cloneWithRows(data)
})
let isNoMore = this._page > 2 //是否已無更多數(shù)據(jù)
//結(jié)束
end(isNoMore)// 假設(shè)加載4頁后數(shù)據(jù)全部加載完畢 加載成功后需要調(diào)用end結(jié)束刷新
},2000)
}
componentDidMount() {
let timer = setTimeout(()=>{
clearTimeout(timer)
this.refs.listView.beginRefresh()
},500) //自動調(diào)用開始刷新 新增方法
}
/*--tip--:如果刷新和加載在同一個方法里婉烟,對于傳遞的參數(shù)end()函數(shù)無需區(qū)分娩井。
onRefresh中的end()函數(shù) 中接受參數(shù)沒有任何關(guān)系 只要調(diào)用end()函數(shù)就會結(jié)束刷新或加載*/