小程序自定義下拉刷新(Taro版)

在考慮實現自定義的下拉刷新組件的時候,首先要明確,這個算是一種hack方案。並非說自定義的有多麼好,反而自定義的下拉刷新在android下會有細微的卡頓(我這種實現方式)。因此儘可能仍是用小程序自帶的吧。html

這個實現主要是參考艾倫大佬的組件android

實現方式

咱們將頁面分爲下面的結構ios

foo

正常的時候下拉刷新區域的高度爲0git

而後咱們經過scroll-viewscrollToUpeper事件來標記開始下滑。github

經過touchstart來記錄咱們手指的初始位置。typescript

經過監聽列表區域touchmove事件,來不斷的計算手指移動距離。小程序

touchend事件來觸發更新事件。性能

咱們將頁面分爲幾種狀態:flex

enum refreshStatus {
  INIT,
  PULL_DOWN,
  READY_REFRESH,
  LOADING,
  DONE
}
複製代碼

大體流程以下:this

  1. 頁面加載以後是INIT狀態。

  2. 當觸發了scroll-viewscrollToUpeper事件,咱們記錄一個標誌位isUpper,在scroll-viewscroll事件觸發時,isUpper記爲false

  3. 當咱們列表頁滑倒頂部的時候再下拉,頁面進入了PULL_DOWN狀態。 通常會設置一個有效的下拉距離,稱之爲validHeight,當下拉的高度不足validHeight時,這時候鬆開手指,頁面回彈不刷新。

  4. 當咱們繼續下拉,距離超過了validHeight這時候進入了READY_REFRESH狀態。

  5. READY_REFRESH狀態的時候放開手指,頁面刷新,進入LOADING狀態。

  6. 頁面刷新完畢以後,進入DONE狀態,刷新區域高度變爲0

咱們還須要設置一個最大下拉高度,以及在READY_REFRESH狀態,手指放開後回彈到刷新區域的最大高度。

至此咱們能夠寫出touchendtouchstarttouchmove 代碼大體以下:(詳細代碼

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整個頁面跟着下滑的問題。

對比原生的下拉刷新

  1. android下會有稍微的卡頓,ios和模擬器體驗比較好。

  2. 能夠頁面局部的下拉刷新。刷新的樣式也能夠定製化。

結語

其實在ios下還有一種實現方式,利用的就是iosscroll-view在拉到頂部的時候還能夠往下拉(橡皮筋效果),這時候咱們能夠把刷新的區域放在scroll-view但是區域上面。性能上確定要比不斷的計算高度來的要好。

可是有兩個問題:

  1. 不能再頁面中局部使用,由於局部使用的話就須要禁用頁面滾動,這也跟着禁用了ios的橡皮筋效果,從而使咱們的下拉刷新不能用

  2. 手指放開以後有個輕微的回彈效果,雖然無傷大雅,可是感受仍是挺奇怪的。

這種實現方式下次我也貼出來,也能夠參照艾倫的博客,他說的比較詳細,我也主要是參考他的代碼來實現的。

相關文章
相關標籤/搜索