亚洲免费在线观看_av网站免费观看_亚洲视频中文字幕_日本视频在线_香蕉一区二区_国产精品中文_这里只有精品久久_欧美一区二区三区不卡_日本高清在线观看_国产精品免费一区二区三区都可以_欧美黄色大片视频_自拍偷拍第1页_亚洲啪av永久无码精品放毛片_三级免费观看_日日狠狠_波多野结衣绝顶大高潮_国语一级片_亚洲丁香婷婷

027-81331413

小程序下拉刷新樣式

發(fā)布時間:2020-10-30 瀏覽:3753

在微信小程序開發(fā)中實現(xiàn)下拉刷新最簡單的方式就是在頁面對應(yīng)的json文件中添加enablePullDownRefresh:true,然后在Page.onPullDownRefresh 方法中執(zhí)行刷新邏輯。這種方式有一些局限性,一是無法自定義下拉刷新效果,只能使用默認(rèn)的“三個圓點”樣式;二是下拉刷新的視圖位置是固定在頂部的,如果要刷新的視圖元素不是位于頁面頂部,那么使用這種方式就不太好了,最常見的場景就是頂部Tab標(biāo)簽欄,下面是要刷新的列表。在小程序基礎(chǔ)庫版本2.10.1之后,scroll-view支持自定義下拉刷新了,很好地解決了上述的兩個問題,缺點當(dāng)然就是兼容性了。于是想著自己實現(xiàn)一個下拉刷新組件,由于我本身是做Android開發(fā)的,所以嘗試實現(xiàn)了一個仿Material Design風(fēng)格的下拉刷新效果(Android中的SwipeRefeshLayout),先附上一張效果圖:

 
雖然沒能做到百分之百的還原,不過基本功能還是實現(xiàn)了的。相關(guān)代碼我已經(jīng)上傳到了github。
 
使用方式
將組件拷貝到項目中,在頁面的json文件中引入,這里就不展示了。組件可設(shè)置的屬性如下:
 

此外,組件還定義了一個setRefresh()函數(shù),用于設(shè)置刷新狀態(tài),參數(shù)傳入一個布爾值,true表示開始刷新,顯示下拉刷新圓圈;false表示結(jié)束刷新,隱藏下拉刷新圓圈。
示例代碼如下:
index.wxml
 
<swipe-refresh-layout id='refresh' style='width:100vw;height:200rpx;' loadMoreEnable bindrefresh='refresh' bindloadmore='loadMore'>
  <!-- 要刷新的內(nèi)容 -->
</swipe-refresh-layout>
index.js
 
Page({
 
  /**
   * 頁面的初始數(shù)據(jù)
   */
  data: {},
 
  /**
   * 生命周期函數(shù)--監(jiān)聽頁面加載
   */
  onLoad: function(options) {
    this.swipeRefresh = this.selectComponent('#refresh');
  },
 
  /**
   * 下拉刷新
   */
  refresh: function() {
    // 模擬獲取數(shù)據(jù)
    setTimeout(() => {
      // 結(jié)束下拉刷新
      this.swipeRefresh.setRefresh(false);
    }, 3000);
  },
 
  /**
   * 上拉加載
   */
  loadMore: function() {
    // ...
  }
})
需要注意,使用時必須給swipe-refresh-layout組件一個固定的寬度和高度。
 
實現(xiàn)原理
實現(xiàn)原理還是比較簡單的,大體上就是通過監(jiān)聽觸摸事件,在touchstart事件回調(diào)中記錄手指按下的坐標(biāo);在touchmove事件回調(diào)中計算手指在豎直方向上的滑動距離,通過css的transform屬性實現(xiàn)下拉刷新圓圈的移動;在touchend事件回調(diào)中計算手指抬起時的滑動距離,如果向下的滑動距離超過閾值就觸發(fā)下拉刷新事件,否則將下拉刷新圓圈歸位。由于在滑動的過程中需要頻繁地進行用戶交互,出于性能方面的考慮,我使用了WXS函數(shù)用來響應(yīng)觸摸事件,將事件定義在視圖層,解決視圖層和邏輯層間通信耗時的問題。
雖然整體的實現(xiàn)邏輯不難理解,但是在開發(fā)過程中我還是遇到了幾個問題,這里簡單介紹一下。
 
touchmove導(dǎo)致的卡頓問題
一開始我使用的是bindtouchmove屬性監(jiān)聽手指滑動事件,在開發(fā)工具上測試時沒有什么問題,后來運行在安卓真機上才發(fā)現(xiàn)手指觸摸屏幕下拉時刷新圓圈的移動比較卡頓,不流暢。在微信開放社區(qū)查了一下這個問題,發(fā)現(xiàn)也有人遇到過,目前的解決方案就是將bindtouchmove改為catchtouchmove。具體原因還不清楚,可能是官方的bug吧,又或者小程序本身就是這樣設(shè)計的。改為catchtouchmove后確實是解決了下拉卡頓的問題,但是同時會導(dǎo)致頁面內(nèi)容無法滑動,如何解決這個問題呢,我們不妨考慮一下具體的使用場景,正常情況下只有在頁面內(nèi)容處于頂部時才可以下拉刷新,可以利用這個條件來判斷是否需要我們自己處理touchmove事件。具體的做法是這樣的,首先在組件最外層使用scroll-view,通過bindscroll監(jiān)聽滑動事件:
 
_scroll: function(e) {
  if (e.detail.scrollTop <= 50) {
    // 滾動到頂部
    this.setData({
      scrollTop: true
    });
  } else {
    this.setData({
      scrollTop: false
    });
  }
}
使用一個變量scrollTop來記錄是否滑動到了頂部,這里的判斷條件為什么是e.detail.scrollTop <= 50而不是e.detail.scrollTop <= 0呢,因為通過測試我發(fā)現(xiàn)有時頁面滑動到頂部時e.detail.scrollTop的值并不是0,而是一個接近0的整數(shù),為了保證每次頁面滑動到頂部都能改變scrollTop的狀態(tài),這里就給了一個默認(rèn)值,取50是因為官方文檔上給出的默認(rèn)閾值就是50。
 
 
之后在catchtouchmove回調(diào)函數(shù)中根據(jù)scrollTop的值判斷是否需要處理滑動事件,如果scrollTop的值為false(頁面內(nèi)容不處位于頂部)就直接return。
 
touchmove: function(e) {
  if (!this.data.scrollTop) {
    return;
  }
  // 處理滑動事件
  
}
這樣就解決了頁面內(nèi)容始終無法滾動的問題,當(dāng)然上面的代碼只是簡單地說明解決方法,詳細(xì)內(nèi)容可以參考組件的源碼。
 
下拉刷新圓圈的顯示層級問題
正常情況下下拉刷新圓圈是位于要刷新的內(nèi)容之上的,并且不會隨著內(nèi)容的滑動而移動,我們很容易就想到使用position:fixed屬性,通過z-index屬性來設(shè)置元素的層疊順序。但是如果下拉刷新圓圈的z-index指定一個大于0的數(shù),而刷新組件又不是位于頁面的頂部,就會導(dǎo)致下拉刷新圓圈始終會顯示出來,如下圖所示:

 
我這里采取的解決方案就是將下拉刷新圓圈的z-index指定為-1,而刷新內(nèi)容的z-index指定為-2(取值不是固定的,只要比下拉刷新圓圈的小就可以),這樣就可以解決下拉刷新圓圈覆蓋在頁面普通視圖之上的問題。當(dāng)然我的解決方案可能不是最好的,或者存在一些問題,如果大家有自己的想法歡迎提出,一起交流。