*本篇文章已授權(quán)微信公眾號(hào) guolin_blog (郭霖)獨(dú)家發(fā)布
本文為原創(chuàng),轉(zhuǎn)載必須保留出處归薛!
http://www.reibang.com/p/1a82cdab2249
有更新:
- 最新的庫(kù)版本為1.0.2(兼容舊版本轰坊,舊版本是1.0.0)冀宴,完整的庫(kù)地址:
compile'com.zt.maven.widget:refreshview:1.0.2'
- 更新說(shuō)明:
1 - 反注冊(cè)DataObserver時(shí)添加判斷火本,避免使用時(shí)多次調(diào)用產(chǎn)生bug
2 - 私有化com.android.support:appcompat-v7危队,避免使用時(shí)版本沖突
寫在前面:
一個(gè)支持網(wǎng)絡(luò)錯(cuò)誤重試、無(wú)數(shù)據(jù)頁(yè)(可自定義)钙畔、無(wú)網(wǎng)絡(luò)界面(可自定義)的上拉加載更多交掏,下拉刷新控件。
-
話不多說(shuō)(無(wú)圖說(shuō)個(gè)??)
效果(由于模擬器有點(diǎn)卡頓刃鳄,但所有效果都展示出來(lái)了).gif 為了滿足大家活多事急找來(lái)即用的心態(tài)盅弛,我先上干貨,怎么用叔锐?
基本用法(分為1挪鹏,2,3步)
ps:如果項(xiàng)目需要更加完善的ui顯示愉烙,如:進(jìn)入后界面自動(dòng)刷新讨盒、網(wǎng)絡(luò)錯(cuò)誤重試、無(wú)數(shù)據(jù)頁(yè)(可自定義)步责、無(wú)網(wǎng)絡(luò)界面(可自定義)的功能請(qǐng)接著前三步往下看返顺、往下看
- 項(xiàng)目中添加依賴
最新版本(兼容舊版本): compile 'com.zt.maven.widget:refreshview:1.0.2'
舊版本:compile 'com.zt.maven.widget:refreshview:1.0.0'
-
初始化控件
可動(dòng)態(tài)代碼引入禀苦,也可靜態(tài)xml添加,依個(gè)人喜好和實(shí)際情況 - 調(diào)用
refreshView.setOnLoadListener(new CustomRefreshView.OnLoadListener() {
@Override
public void onRefresh() {
//下拉刷新遂鹊,添加你刷新后的邏輯
//加載完成時(shí)振乏,隱藏控件下拉刷新的狀態(tài)
refreshView.complete();
}
@Override
public void onLoadMore() {
//上拉加載更多,添加你加載數(shù)據(jù)的邏輯
//加載完成時(shí)秉扑,隱藏控件上拉加載的狀態(tài)
refreshView.complete();
}
});
API擴(kuò)充:
-
列表自動(dòng)刷新
如需進(jìn)入頁(yè)面后自動(dòng)刷新列表數(shù)據(jù)慧邮,請(qǐng)?jiān)诓襟E3完成后添加:
refreshView.setRefreshing(true);
-
無(wú)數(shù)據(jù)界面添加
如果首次刷新無(wú)數(shù)據(jù),需要顯示無(wú)數(shù)據(jù)的占位圖舟陆,可以在你加載完成時(shí)误澳,根據(jù)后端接口返回的數(shù)據(jù)(一定是請(qǐng)求第一頁(yè)且返回?zé)o數(shù)據(jù)的情況下)添加相應(yīng)的占位圖(上圖gif中的“暫無(wú)數(shù)據(jù)”界面即控件中默認(rèn)的,如果符合那恭喜你直接用即可秦躯,下面會(huì)寫明調(diào)用方法忆谓。如果不符合你的審美或者和你的項(xiàng)目整體風(fēng)格不一致,沒(méi)關(guān)系踱承,你只需把你的無(wú)數(shù)據(jù)占位圖寫好倡缠,api調(diào)用時(shí)當(dāng)作參數(shù)傳遞即可,下面也會(huì)寫明調(diào)用方法勾扭,很簡(jiǎn)單)毡琉,并且依舊可以下拉刷新铁瞒。
- 直接用控件中的默認(rèn)無(wú)數(shù)據(jù)占位圖:
refreshView.setEmptyView("暫無(wú)數(shù)據(jù)");
(注:默認(rèn)的占位圖界面文字顯示也可以自己定義)
- 使用自己寫的無(wú)數(shù)據(jù)占位圖(如customView)妙色,填入如下API的參數(shù)中
refreshView.setCreateView(customView);
-
無(wú)網(wǎng)絡(luò)或加載失敗頁(yè)添加
如果項(xiàng)目中需要在無(wú)網(wǎng)絡(luò)或者加載失敗的情況下(根據(jù)接口數(shù)據(jù)返回)添加相應(yīng)的ui給用戶一個(gè)友好的交互,那么你可以直接調(diào)用慧耍,當(dāng)然也可以寫自己風(fēng)格的ui身辨,下面我會(huì)一一給出用法,并且依舊可以下拉刷新
(ps:這里需要闡明一個(gè)邏輯問(wèn)題芍碧,顯示無(wú)網(wǎng)絡(luò)界面或加載出錯(cuò)界面只能在你首次請(qǐng)求數(shù)據(jù)失敗的情況下煌珊。why?試想如果你的用戶已經(jīng)加載出了一頁(yè)數(shù)據(jù)泌豆,這時(shí)突然間沒(méi)網(wǎng)絡(luò)了或者剛好服務(wù)器出了點(diǎn)問(wèn)題導(dǎo)致請(qǐng)求失敗定庵,你這時(shí)給用戶顯示一個(gè)網(wǎng)絡(luò)出錯(cuò)頁(yè)覆蓋了已經(jīng)有的數(shù)據(jù),信不信踪危,你家產(chǎn)品經(jīng)歷已經(jīng)拿著40米的砍刀等著你跑39米蔬浙。。還有一個(gè)提示的地方贞远,有朋友說(shuō)這個(gè)和無(wú)數(shù)據(jù)占位圖沒(méi)什么區(qū)別畴博,其實(shí)區(qū)別在于一個(gè)是請(qǐng)求成功但是無(wú)數(shù)據(jù),一個(gè)是請(qǐng)求失斃吨佟)
- 使用引入控件中的默認(rèn)加載失斁悴 (無(wú)網(wǎng)絡(luò))占位圖-效果如上圖gif的重試界面
refreshView.setErrorView();
- 使用自己寫的加載失敼倨!(無(wú)網(wǎng)絡(luò))占位圖
這里的重試按鈕點(diǎn)擊進(jìn)行重新加載的過(guò)程你只需在你的點(diǎn)擊事件中加入refreshView.setRefreshing(true);即可。用法:
refreshView.setCreateView(errorView)
-
加載失敗重試機(jī)制
如果項(xiàng)目中需要支持加載失敗時(shí)重試機(jī)制(這里指已經(jīng)加載出數(shù)據(jù)但是在加載下一頁(yè)數(shù)據(jù)失敗時(shí)亮隙,點(diǎn)擊底部變更的ui進(jìn)行加載途凫,詳見上圖gif加載更多時(shí)顯示點(diǎn)擊重試),當(dāng)然控件也滿足需求咱揍,調(diào)用時(shí)需要判斷是否時(shí)大于第一頁(yè)(注:有的公司接口規(guī)定從0開始颖榜,有的從1開始),這里還有一點(diǎn)要注意:如果當(dāng)前不是首頁(yè)的情況下加載失敗煤裙,你需要將你的頁(yè)碼數(shù)減一掩完,否則會(huì)跳過(guò)本頁(yè)數(shù)據(jù)展示,用法如下:
refreshView.onError();
為了便于理解硼砰,我貼出我項(xiàng)目的具體做法且蓬,并給出解釋:
@Override
public void onFail(TinaException exception) {
if (m > 1) {
size = size - 1;
refreshView.onError();
} else {
refreshView.setErrorView();
}
refreshView.complete();
}
代碼解釋: onFail方法表示加載出錯(cuò),m標(biāo)記著是否是第一頁(yè)數(shù)據(jù)(個(gè)人項(xiàng)目中請(qǐng)求頁(yè)碼從1開始)题翰,如果大于第一頁(yè)時(shí)恶阴,頁(yè)面數(shù)要減一,以保證數(shù)據(jù)不會(huì)遺漏加載豹障。onError()方法處理了加載失敗的ui顯示和點(diǎn)擊ui重新加載的機(jī)制冯事。else里面代表當(dāng)?shù)谝豁?yè)數(shù)據(jù)加載失敗時(shí)顯示的占位。血公,complete():表示隱藏刷新的ui昵仅。項(xiàng)目最后會(huì)貼出項(xiàng)目demo地址,你可以自己再體會(huì)累魔。
-
加載完成狀態(tài)
當(dāng)所有數(shù)據(jù)加載加載完畢時(shí)摔笤,變更地步ui狀態(tài)為"-- 沒(méi)有更多了 --"
refreshView.onNoMore();
下面是一些顯示細(xì)節(jié)補(bǔ)充和實(shí)現(xiàn)
控件默認(rèn)支持線性布局
變更下拉刷新的ui圓圈顏色
refreshView.getSwipeRefreshLayout().setColorSchemeColors(getResources().getColor());禁止下拉刷新
refreshView.setRefreshEnable(false);禁止加載更多
refreshView.setLoadMoreEnable(false);目前項(xiàng)目中不支持自動(dòng)添加頭部,如需實(shí)現(xiàn)添加頭部垦写,可在第一頁(yè)返回?cái)?shù)據(jù)中的第一個(gè)位置添加一條偽造數(shù)據(jù)吕世,然后在adapter中添加多種item判斷,如果position=0梯投,則顯示頭部命辖。(ps: 這樣有個(gè)弊端:首頁(yè)數(shù)據(jù)加載失敗時(shí),頭部也顯示不出來(lái),其實(shí)也不太影響分蓖,如果一個(gè)上線項(xiàng)目數(shù)據(jù)一直加載失敗尔艇,這后臺(tái)該多大的鍋),后面會(huì)把這部分缺失補(bǔ)充咆疗,敬請(qǐng)期待漓帚。
關(guān)于控件:
內(nèi)部實(shí)現(xiàn)是通過(guò)SwipeRefreshLayout + recyclerView,通過(guò)將數(shù)據(jù)轉(zhuǎn)換到控件內(nèi)部的包裝類WrapperAdapter獲取數(shù)據(jù)進(jìn)行加載更多的item包裝午磁。使用DataObserver來(lái)檢測(cè)數(shù)據(jù)源的變化尝抖,來(lái)顯示正常數(shù)據(jù)界面毡们、無(wú)網(wǎng)絡(luò)、無(wú)數(shù)據(jù)界面昧辽。
項(xiàng)目源碼demo地址衙熔,如有幫助請(qǐng)star
ps : 由于無(wú)網(wǎng)絡(luò)、無(wú)數(shù)據(jù)界面搅荞、還有加載重試機(jī)制在真實(shí)的情況下不好復(fù)現(xiàn)红氯,為了所有情況都展示出來(lái)以便大家觀看,因此demo中的數(shù)據(jù)是自己模擬的