之前寫iOS時,有這非常好用的下拉刷新和上拉加載的組件如MJReferesh這樣優秀的組件,但是最近寫ReactNative時,一直沒發現非常如意的第三方下拉刷新的組件,所以便自己寫了一個簡單好用的刷新組件react-native-swRefresh,支持scrollView,ListView,支持自定義。支持iOS和Android
更新Android支持 實現方式不一樣 所以Android體驗可能稍微有點不同
新增beginRefresh()和endRefresh()方法來手動調用下拉刷新和結束下拉刷新 類iOS中的MJRefrsh
新增endLoadMore() 結束上拉加載 代替end()回調 同樣可以傳入bool參數代表這次結束是否進入已無更多狀態。
因為剛接觸,所以也寫不出非常優美的代碼,改著改著就有點冗余了,有空就優化下,但是個人覺的應該是很好用的組件,這篇文章主要是介紹其如何使用:
-
安裝:
npm install react-native-swRefresh
-
使用:
- 引入
//根據需要引入
import {
SwRefreshScrollView, //支持下拉刷新的ScrollView
SwRefreshListView, //支持下拉刷新和上拉加載的ListView
RefreshStatus, //刷新狀態 用于自定義下拉刷新視圖時使用
LoadMoreStatus //上拉加載狀態 用于自定義上拉加載視圖時使用
} from 'react-native-swRefresh'
具體屬性和方法 github上有介紹
- 簡單使用(兩個組件下拉刷新的使用方法是一樣的,本文以SwRefreshListView為例)
_page = 0
_dataSource = new ListView.DataSource({rowHasChanged:(row1,row2)=>row1 !== row2})
// 構造
constructor(props) {
super(props);
// 初始狀態
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)}//設置下拉刷新的方法 傳遞參數end函數 當刷新操作結束時
onLoadMore={this._onLoadMore.bind(this)} //設置上拉加載執行的方法 傳遞參數end函數 當刷新操作結束時 end函數可接受一個bool值參數表示刷新結束后是否已經無更多數據了。
//isShowLoadMore={false} //可以通過state控制是否顯示上拉加載組件,可用于數據不足一屏或者要求數據全部加載完畢時不顯示上拉加載控件
customRefreshView={(refresStatus,offsetY)=>{
return (<Text>{'狀態:'+refresStatus+','+offsetY}</Text>)
}} //自定義下拉刷新視圖參數,refresStatus是上面引入的RefreshStatus類型,對應刷新狀態各個狀態。offsetY對應下拉的偏移量,可用于定制動畫。自定義視圖必須通過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)
})
//推薦以下寫法 用戶體驗更好
if(已加載全部數據){
//如果此時刷新的數據就已經是全部數據了,不管怎樣都應該將上拉加載組件設置為沒有更多數據了的狀態 或者通過isShowLoadMore控制其隱藏
this.refs.listView.setNoMoreData() //設置為沒有更多數據了的狀態
}else{
//這里調用resetStatus來重置上拉加載的狀態 因為此前可上拉加載組件的狀態可能已經是無更多數據了 所以進行狀態重置 亦可以通 過state控制isShowLoadMore來控制顯示上拉加載視圖
this.refs.listView.resetStatus() //重置上拉加載的狀態
}
//如果不這么寫 上拉一次后 上拉組件也會獲知正確的狀態
end()//刷新成功后需要調用end結束刷新 不管成功或者失敗都應該結束
/ / this.refs.listView.endRefresh() //新增方法 結束刷新 建議使用end() 。當然這個可以在任何地方使用
},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 //是否已無更多數據
//結束
end(isNoMore)// 假設加載4頁后數據全部加載完畢 加載成功后需要調用end結束刷新
},2000)
}
componentDidMount() {
let timer = setTimeout(()=>{
clearTimeout(timer)
this.refs.listView.beginRefresh()
},500) //自動調用開始刷新 新增方法
}
/*--tip--:如果刷新和加載在同一個方法里,對于傳遞的參數end()函數無需區分。
onRefresh中的end()函數 中接受參數沒有任何關系 只要調用end()函數就會結束刷新或加載*/
演示:

image

image

image

image