在考慮實現自定義的下拉刷新組件的時候,首先要明確,這個算是一種hack方案。並非說自定義的有多麼好,反而自定義的下拉刷新在
android
下會有細微的卡頓(我這種實現方式)。因此儘可能仍是用小程序自帶的吧。html這個實現主要是參考艾倫大佬的組件。android
咱們將頁面分爲下面的結構ios
正常的時候下拉刷新區域的高度爲0
。git
而後咱們經過scroll-view
的scrollToUpeper
事件來標記開始下滑。github
經過touchstart
來記錄咱們手指的初始位置。typescript
經過監聽列表區域的touchmove
事件,來不斷的計算手指移動距離。小程序
touchend
事件來觸發更新事件。性能
咱們將頁面分爲幾種狀態:flex
enum refreshStatus {
INIT,
PULL_DOWN,
READY_REFRESH,
LOADING,
DONE
}
複製代碼
大體流程以下:this
頁面加載以後是INIT
狀態。
當觸發了scroll-view
的scrollToUpeper
事件,咱們記錄一個標誌位isUpper
,在scroll-view
的scroll
事件觸發時,isUpper
記爲false
當咱們列表頁滑倒頂部的時候再下拉,頁面進入了PULL_DOWN
狀態。 通常會設置一個有效的下拉距離,稱之爲validHeight
,當下拉的高度不足validHeight
時,這時候鬆開手指,頁面回彈不刷新。
當咱們繼續下拉,距離超過了validHeight
這時候進入了READY_REFRESH
狀態。
在READY_REFRESH
狀態的時候放開手指,頁面刷新,進入LOADING
狀態。
頁面刷新完畢以後,進入DONE
狀態,刷新區域高度變爲0
咱們還須要設置一個最大下拉高度,以及在READY_REFRESH
狀態,手指放開後回彈到刷新區域的最大高度。
至此咱們能夠寫出touchend
、touchstart
、touchmove
代碼大體以下:(詳細代碼)
handleTouchMove(e) {
const curTouch = e.touches[0]
const moveY = (curTouch.pageY - this.lastTouchY) * .3
if(
!this.isUpper ||
moveY < 0 ||
moveY > 2 * this.maxHeight ||
this.state.refreshStatu === refreshStatus.LOADING
) {
return
}
if(moveY < this.validHeight) {
this.setState({
refreshHeight: moveY,
refreshStatu: refreshStatus.PULL_DOWN
})
} else {
this.setState({
refreshHeight: moveY,
refreshStatu: refreshStatus.READY_REFRESH
})
}
}
handleTouchStart(e) {
const curTouch = e.touches[0]
this.lastTouchY = curTouch.pageY
}
handleTouchEnd() {
this.lastTouchY = 0
if(this.state.refreshStatu === refreshStatus.READY_REFRESH) {
this.setState({
refreshStatu: refreshStatus.LOADING,
refreshHeight: this.maxHeight
})
if (this.props.onRefresh) {
this.props.onRefresh()
}
} else {
this.setState({
refreshHeight: 0
})
}
}
handleScrollToUpeper() {
this.isUpper = true
}
handleScroll() {
this.isUpper = false
}
複製代碼
除此以外,咱們還須要在調用的頁面上加上disableScroll: true
的配置,以解決ios整個頁面跟着下滑的問題。
android下會有稍微的卡頓,ios和模擬器體驗比較好。
能夠頁面局部的下拉刷新。刷新的樣式也能夠定製化。
其實在ios
下還有一種實現方式,利用的就是ios
的scroll-view
在拉到頂部的時候還能夠往下拉(橡皮筋效果),這時候咱們能夠把刷新的區域放在scroll-view
但是區域上面。性能上確定要比不斷的計算高度來的要好。
可是有兩個問題:
不能再頁面中局部使用,由於局部使用的話就須要禁用頁面滾動,這也跟着禁用了ios的橡皮筋效果,從而使咱們的下拉刷新不能用
手指放開以後有個輕微的回彈效果,雖然無傷大雅,可是感受仍是挺奇怪的。
這種實現方式下次我也貼出來,也能夠參照艾倫的博客,他說的比較詳細,我也主要是參考他的代碼來實現的。