當然,完全可以自己動手通過自定義view來實現(xiàn)下拉刷新的功能,但是具體實現(xiàn)起來還是比較麻煩的。如果有興趣,可以參考慕課網(wǎng)上的相關視屏
傳送門
但是目前我們有更加方便的方法來實現(xiàn)這樣的功能,google已經(jīng)為我們提供了一個上拉刷新與下拉加載更多的控件。
SwipeRefreshLayout。現(xiàn)在就通過這個控件為recyclerView添加上拉刷新與下載功能。
SwipeRefreshLayout包含在V4的jar包中,不需要特殊的導入,更多細節(jié)請參考:官方參考文檔
接下來就學習怎么使用:
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swipeRefreshLayout"
android:layout_width="368dp"
android:layout_height="495dp"
android:scrollbars="vertical"
tools:layout_editor_absoluteY="8dp"
tools:layout_editor_absoluteX="8dp">
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler"
android:layout_width="368dp"
android:layout_height="495dp"
android:background="#ccc"
tools:layout_editor_absoluteX="8dp"
tools:layout_editor_absoluteY="8dp" />
</android.support.v4.widget.SwipeRefreshLayout>
在MainActivity中添加監(jiān)聽事件即可實現(xiàn):
主要代碼如下:
mSwipRefreshLayout.setProgressBackgroundColorSchemeResource(android.R.color.white);
mSwipRefreshLayout.setColorSchemeResources(android.R.color.holo_blue_light,
android.R.color.holo_red_light,android.R.color.holo_orange_light,
android.R.color.holo_green_light);
mSwipRefreshLayout.setProgressViewOffset(false, 0, (int) TypedValue
.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 24, getResources()
.getDisplayMetrics()));
//設置進度條的顏色
mSwipRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener(){
@Override
public void onRefresh() {
//模仿加載數(shù)據(jù)
//加載更多的邏輯在這里進行實現(xiàn)
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
loadMoreData();//加載數(shù)據(jù)
}
},2000);
//加載完畢后,記得將設置運行狀態(tài)為false,隱藏進度條的顯示
mSwipRefreshLayout.setRefreshing(false);
}
});
到此,只需要實現(xiàn)加載數(shù)據(jù)和通知數(shù)據(jù)更新即可,這里不是我們的重點。我們就實現(xiàn)了下拉刷新的功能。、
然后,我們在來實現(xiàn)當我們拉到底的時候,加載更多。
參考鏈接:https://www.easydone.cn/2015/10/26/
為了代碼的獨立性,我們單獨將其主要實現(xiàn)的方法封裝在一個抽象類中:
要實現(xiàn)下拉刷新,我們首先要考慮的是,我們什么時候開始刷新、依據(jù)是什么。
public abstract class DropDownListener extends RecyclerView.OnScrollListener {
//聲明一個LinearLayoutManager
private LinearLayoutManager mLinearLayoutManager;
//當前頁,從0開始
private int currentPage = 0;
//已經(jīng)加載出來的Item的數(shù)量
private int totalItemCount;
//主要用來存儲上一個totalItemCount
private int previousTotal = 0;
//在屏幕上可見的item數(shù)量
private int visibleItemCount;
//在屏幕可見的Item中的第一個
private int firstVisibleItem;
//是否正在上拉數(shù)據(jù)
private boolean loading = true;
public DropDownListener(LinearLayoutManager linearLayoutManager) {
this.mLinearLayoutManager = linearLayoutManager;
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
visibleItemCount = recyclerView.getChildCount();
totalItemCount = mLinearLayoutManager.getItemCount();
firstVisibleItem = mLinearLayoutManager.findFirstVisibleItemPosition();
if (loading) {
if (totalItemCount > previousTotal) {
//說明數(shù)據(jù)已經(jīng)加載結束
loading = false;
previousTotal = totalItemCount;
}
}
//當沒有在加載且 已經(jīng)加載出來的item數(shù)量-屏幕上可見的item數(shù)量<=屏幕上可見的第一個item的序號(即已經(jīng)滑倒底的時候)
//執(zhí)行相應的操作
if (!loading && totalItemCount - visibleItemCount <= firstVisibleItem) {
currentPage++;
onLoadMore(currentPage);
loading = true;
}
}
/**
* 提供一個抽閑方法,在Activity中監(jiān)聽到這個EndLessOnScrollListener
* 并且實現(xiàn)這個方法
*/
public abstract void onLoadMore(int currentPage);
}
然后,我們調(diào)用的時候就很簡單了。關鍵代碼如下:
mRecyclerView.addOnScrollListener(new DropDownListener((LinearLayoutManager) mManager) {
@Override
public void onLoadMore(int currentPage) {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
loadMoreData();
}
},2000);
}
});
到此,我們就實現(xiàn)了簡單的下拉刷新、上拉加載的功能。如圖;

可以看到,我們的確是實現(xiàn)了上拉加載、下拉刷新的功能。但是在下拉加載的時候,并沒有任何提示,
這一點是非常不友好的。于是、我們繼續(xù)來改進。
因為我們之前實現(xiàn)了添加header和footer的功能。所以,比較簡單的一種思想就是
直接添加footer當作我們下拉刷新的提示。當刷新完成的時候,隱藏footer就ok了。
下面我們來實現(xiàn)代碼:
將footer改造成我們想要的效果即可,譬如,我將footer設置呈這樣:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="80dp"
android:background="#fff"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:paddingTop="10dp"
android:textColor="#F00"
android:text="正在加載" />
<ProgressBar
android:id="@+id/progressBar"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</FrameLayout>
然后,設置recyclerView添加footer,設置效果如下:

效果基本達到我們的預想。但是這種方法也有一定的缺點:
代碼地址
- 不能實現(xiàn)自己回彈(即松開手指自動隱藏)
- 不能橫向的獨立出來,這就造成不是很好封裝成一個jar
- 當我們需要一個footer的時候,就無法滿足需求。
正對上面的三點,我們需要需找新的方案來解決這個問題。但是這里就不做介紹了。