一個簡單好用的下拉重新整理、上拉載入控制元件
*本篇文章已授權微信公眾號 guolin_blog (郭霖)獨家釋出
有更新:
- 最新的庫版本為1.0.2(相容舊版本,舊版本是1.0.0),完整的庫地址:
compile'com.zt.maven.widget:refreshview:1.0.2'
- 更新說明:
1 - 反註冊DataObserver時新增判斷,避免使用時多次呼叫產生bug
2 - 私有化com.android.support:appcompat-v7,避免使用時版本衝突
- 更新說明:
寫在前面:
- 一個支援網路錯誤重試、無資料頁(可自定義)、無網路介面(可自定義)的上拉載入更多,下拉重新整理控制元件。
話不多說(無圖說個✖️)
為了滿足大家活多事急找來即用的心態,我先上乾貨,怎麼用?
基本用法(分為1,2,3步)
ps:如果專案需要更加完善的ui顯示,如:進入後介面自動重新整理、網路錯誤重試、無資料頁(可自定義)、無網路介面(可自定義)的功能請接著前三步往下看、往下看
- 專案中新增依賴
最新版本(相容舊版本): compile 'com.zt.maven.widget:refreshview:1.0.2'
舊版本:compile 'com.zt.maven.widget:refreshview:1.0.0'
- 初始化控制元件
可動態程式碼引入,也可靜態xml新增,依個人喜好和實際情況 - 呼叫
refreshView.setOnLoadListener(new CustomRefreshView.OnLoadListener() {
@Override
public void onRefresh() {
//下拉重新整理,新增你重新整理後的邏輯
//載入完成時,隱藏控制元件下拉重新整理的狀態
refreshView.complete();
}
@Override
public void onLoadMore() {
//上拉載入更多,新增你載入資料的邏輯
//載入完成時,隱藏控制元件上拉載入的狀態
refreshView.complete();
}
});
API擴充:
- 列表自動重新整理
如需進入頁面後自動重新整理列表資料,請在步驟3完成後新增:
refreshView.setRefreshing(true);
- 無資料介面新增
如果首次重新整理無資料,需要顯示無資料的佔位圖,可以在你載入完成時,根據後端介面返回的資料(一定是請求第一頁且返回無資料的情況下)新增相應的佔位圖(上圖gif中的“暫無資料”介面即控制元件中預設的,如果符合那恭喜你直接用即可,下面會寫明呼叫方法。如果不符合你的審美或者和你的專案整體風格不一致,沒關係,你只需把你的無資料佔位圖寫好,api呼叫時當作引數傳遞即可,下面也會寫明呼叫方法,很簡單),並且依舊可以下拉重新整理。
- 直接用控制元件中的預設無資料佔位圖:
refreshView.setEmptyView("暫無資料");
(注:預設的佔位圖介面文字顯示也可以自己定義)
* 使用自己寫的無資料佔位圖(如customView),填入如下API的引數中
refreshView.setCreateView(customView);
- 無網路或載入失敗頁新增
如果專案中需要在無網路或者載入失敗的情況下(根據介面資料返回)新增相應的ui給使用者一個友好的互動,那麼你可以直接呼叫,當然也可以寫自己風格的ui,下面我會一一給出用法,並且依舊可以下拉重新整理
(ps:這裡需要闡明一個邏輯問題,顯示無網路介面或加載出錯介面只能在你首次請求資料失敗的情況下。why?試想如果你的使用者已經加載出了一頁資料,這時突然間沒網路了或者剛好伺服器出了點問題導致請求失敗,你這時給使用者顯示一個網路出錯頁覆蓋了已經有的資料,信不信,你家產品經歷已經拿著40米的砍刀等著你跑39米。。還有一個提示的地方,有朋友說這個和無資料佔位圖沒什麼區別,其實區別在於一個是請求成功但是無資料,一個是請求失敗)
- 使用引入控制元件中的預設載入失敗(無網路)佔位圖-效果如上圖gif的重試介面
refreshView.setErrorView();
- 使用自己寫的載入失敗(無網路)佔位圖
這裡的重試按鈕點選進行重新載入的過程你只需在你的點選事件中加入refreshView.setRefreshing(true);即可。用法:
refreshView.setCreateView(errorView)
- 載入失敗重試機制
如果專案中需要支援載入失敗時重試機制(這裡指已經加載出資料但是在載入下一頁資料失敗時,點選底部變更的ui進行載入,詳見上圖gif載入更多時顯示點選重試),當然控制元件也滿足需求,呼叫時需要判斷是否時大於第一頁(注:有的公司介面規定從0開始,有的從1開始),這裡還有一點要注意:如果當前不是首頁的情況下載入失敗,你需要將你的頁碼數減一,否則會跳過本頁資料展示,用法如下:
refreshView.onError();
為了便於理解,我貼出我專案的具體做法,並給出解釋:
@Override
public void onFail(TinaException exception) {
if (m > 1) {
size = size - 1;
refreshView.onError();
} else {
refreshView.setErrorView();
}
refreshView.complete();
}
程式碼解釋: onFail方法表示加載出錯,m標記著是否是第一頁資料(個人專案中請求頁碼從1開始),如果大於第一頁時,頁面數要減一,以保證資料不會遺漏載入。onError()方法處理了載入失敗的ui顯示和點選ui重新載入的機制。else裡面代表當第一頁資料載入失敗時顯示的佔位。,complete():表示隱藏重新整理的ui。專案最後會貼出專案demo地址,你可以自己再體會。
- 載入完成狀態
當所有資料載入載入完畢時,變更地步ui狀態為”– 沒有更多了 –”
refreshView.onNoMore();
下面是一些顯示細節補充和實現
控制元件預設支援線性佈局
變更下拉重新整理的ui圓圈顏色
refreshView.getSwipeRefreshLayout().setColorSchemeColors(getResources().getColor());禁止下拉重新整理
refreshView.setRefreshEnable(false);禁止載入更多
refreshView.setLoadMoreEnable(false);目前專案中不支援自動新增頭部,如需實現新增頭部,可在第一頁返回資料中的第一個位置新增一條偽造資料,然後在adapter中新增多種item判斷,如果position=0,則顯示頭部。(ps: 這樣有個弊端:首頁資料載入失敗時,頭部也顯示不出來,其實也不太影響,如果一個上線專案資料一直載入失敗,這後臺該多大的鍋),後面會把這部分缺失補充,敬請期待。
關於控制元件:
內部實現是通過SwipeRefreshLayout + recyclerView,通過將資料轉換到控制元件內部的包裝類WrapperAdapter獲取資料進行載入更多的item包裝。使用DataObserver來檢測資料來源的變化,來顯示正常資料介面、無網路、無資料介面。
ps : 由於無網路、無資料介面、還有載入重試機制在真實的情況下不好復現,為了所有情況都展示出來以便大家觀看,因此demo中的資料是自己模擬的