一、MaterialRefreshLayout的簡(jiǎn)介
MaterialRefreshLayout是一個(gè)下拉刷新控件,它比官方提供的
SwipeRefreshLayout更漂亮和強(qiáng)大,使用也比較簡(jiǎn)單。支持android 3.0(也就是API 11)以上。下面給出一張官方提供的效果圖,高大上有木有?!
下面是GitHub的地址:
https://github.com/android-cjj/Android-MaterialRefreshLayout
二、MaterialRefreshLayout的使用簡(jiǎn)介 MaterialRefreshLayout的使用基本和SwipeRefreshLayout一樣。
1、在Gradle中引入MaterialRefreshLayout的依賴庫(kù)。 compile 'com.cjj.materialrefeshlayout:library:1.3.0' 2、在布局文件當(dāng)中放置我們的MaterialRefreshLayout。MaterialRefreshLayout里面也可以放置任意列表控件,通過(guò)這種方式可以實(shí)現(xiàn)MaterialRefreshLayout和列表之間的解耦。 <com.cjj.MaterialRefreshLayout android:id="@+id/refresh_view" android:layout_width="match_parent" android:layout_height="match_parent" app:overlay="false" app:progress_colors="@array/material_colors" app:wave_color="#90ffffff" app:wave_height_type="higher" app:wave_show="true" > <android.support.v7.widget.RecyclerView android:id="@+id/hot_ware_list" android:layout_width="match_parent" android:layout_height="match_parent"/> </com.cjj.MaterialRefreshLayout> 上面的布局文件中,最需要介紹的是MaterialRefreshLayout的自定義屬性,overlay以及wave_show。wave_show是設(shè)置是否顯示下面這個(gè)波浪: overlay是設(shè)置MaterialRefreshLayout使用入侵式(true)還是非入侵式(false)。 其中非入侵式的效果如上圖所示,下拉刷新的時(shí)候,列表可以拉動(dòng),列表和MaterialRefreshLayout是視覺(jué)上分開(kāi)的。 入侵式的效果如下圖所示,MaterialRefreshLayout壓在列表之上。 3、代碼中的配置,最簡(jiǎn)單的使用就是:如果要使用下拉加載更多,設(shè)置一下就可以了。然后要設(shè)置下拉刷新和上拉加載更多的回調(diào),也就是在用戶觸發(fā)這兩個(gè)方法只后需要做什么,一般為向服務(wù)器請(qǐng)求(更多)數(shù)據(jù)。
//設(shè)置支持下拉加載更多 refreshLayout.setLoadMore(true); //刷新以及加載回調(diào) refreshLayout.setMaterialRefreshListener(new MaterialRefreshListener() { @Override public void onRefresh(MaterialRefreshLayout materialRefreshLayout) { } @Override public void onRefreshLoadMore(MaterialRefreshLayout materialRefreshLayout) { } });
三、用MaterialRefreshLayout實(shí)現(xiàn)下拉刷新和上拉加載更多
首先,需要說(shuō)明的是,APP在下拉刷新、上拉加載更多的時(shí)候,我們的代碼應(yīng)該做什么。
下拉刷新:下拉刷新就是清除原來(lái)的所有數(shù)據(jù),如果有分頁(yè),把分頁(yè)回到第一頁(yè),然后向服務(wù)器請(qǐng)求數(shù)據(jù),把數(shù)據(jù)顯示出來(lái)以后關(guān)閉下拉刷新。
上拉加載更多:在原來(lái)已有的數(shù)據(jù)的末尾去追加數(shù)據(jù)。把數(shù)據(jù)顯示出來(lái)以后關(guān)閉上拉加載更多。
因此,我們的Adapter需要提供以下兩個(gè)函數(shù):
/** * 下拉刷新,清除原有數(shù)據(jù),添加新數(shù)據(jù) * * @param newData */ public void refreshData(List<Page.Ware> newData) { mDatas.clear(); mDatas.addAll(newData); notifyItemRangeChanged(0, mDatas.size()); } /** * 在原來(lái)數(shù)據(jù)的末尾追加新數(shù)據(jù) * * @param moreData */ public void loadMoreData(List<Page.Ware> moreData) { int lastPosition = mDatas.size(); mDatas.addAll(lastPosition, moreData); notifyItemRangeInserted(lastPosition, moreData.size()); } 然后,需要定義以下變量,其中數(shù)據(jù)是JSON數(shù)據(jù)的bean對(duì)象。
核心代碼如下:
//用于記錄當(dāng)前是第幾頁(yè) private int curPage = 1; //用于記錄一頁(yè)應(yīng)該請(qǐng)求多少條數(shù)據(jù) private int pageSize = 10; //需要顯示的數(shù)據(jù) private List<Page.Ware> wareList; //用于記錄當(dāng)前是何種狀態(tài),在請(qǐng)求完數(shù)據(jù)之后根據(jù)不同的狀態(tài)進(jìn)行不同的操作 private static final int STATE_INIT = 0; private static final int STATE_REFRESH = 1; private static final int STATE_LOAD_MORE = 2; //用于記錄當(dāng)前的狀態(tài) private int curState = 0; //用于記錄總頁(yè)數(shù),在上拉的時(shí)候判斷還有沒(méi)有更多數(shù)據(jù) private int totalPage = 1;
然后,向服務(wù)器請(qǐng)求數(shù)據(jù),實(shí)現(xiàn)getData()方法,在請(qǐng)求成功的時(shí)候,得到數(shù)據(jù),這個(gè)數(shù)據(jù)可能是初始化的時(shí)候的數(shù)據(jù)、下拉刷新的數(shù)據(jù)、或者上拉加載更多的“更多數(shù)據(jù)”。服務(wù)器的Uri的請(qǐng)求參數(shù)需要有當(dāng)前頁(yè)以及頁(yè)的大小。
核心代碼如下:
private void getData() { String uri = "http://112.124.22.238:8081/course_api/wares/hot?curPage=" + curPage + "&pageSize=" + pageSize; httpHelper.get(uri, newBaseCallback<Page>() { .....其他復(fù)寫(xiě)的方法省略 @Override public void onSuccess(Response response, Page page) { wareList = page.getWareList(); totalPage = page.getTotalPage(); showData(); } }); }
實(shí)現(xiàn)showData()方法,把得到的數(shù)據(jù)顯示多來(lái)。這里需要判斷是初始化狀態(tài)、下拉刷新?tīng)顟B(tài)、上拉加載更多狀態(tài)。不同狀態(tài)干不同的事情:
初始化狀態(tài):初始化列表。
下拉刷新?tīng)顟B(tài):刷新數(shù)據(jù),列表回到最頂端,關(guān)閉下拉刷新
上拉加載更多狀態(tài):追加數(shù)據(jù),關(guān)閉上拉加載更多
核心代碼如下:
private void showData() { switch (curState) { case STATE_INIT: //初始化狀態(tài),初始化列表 mAdapter = newHotWaresListAdapter(wareList, getActivity()); hotWareList.setAdapter(mAdapter); hotWareList.setLayoutManager(new LinearLayoutManager(getActivity())); hotWareList.setItemAnimator(new DefaultItemAnimator()); break; case STATE_REFRESH: //下拉刷新?tīng)顟B(tài),刷新數(shù)據(jù),列表回到最頂端,關(guān)閉下拉刷新 mAdapter.refreshData(wareList); hotWareList.scrollToPosition(0); refreshLayout.finishRefresh(); break; case STATE_LOAD_MORE: //上拉加載更多狀態(tài),追加數(shù)據(jù),關(guān)閉上拉加載更多 mAdapter.loadMoreData(wareList); refreshLayout.finishRefreshLoadMore(); break; } }
四、完整代碼 import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.support.v7.widget.DefaultItemAnimator; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Toast; import com.cjj.MaterialRefreshLayout; import com.cjj.MaterialRefreshListener; import com.lidroid.xutils.ViewUtils; import com.lidroid.xutils.view.annotation.ViewInject; import com.nan.cnshop.R; import com.nan.cnshop.adapter.HotWaresListAdapter; import com.nan.cnshop.bean.Page; import com.nan.cnshop.http.BaseCallback; import com.nan.cnshop.http.OkHttpHelper; import com.nan.cnshop.widget.CNToolbar; import com.squareup.okhttp.Request; import com.squareup.okhttp.Response; import java.util.List; public class HotFragment extends Fragment { @ViewInject(R.id.toolbar) private CNToolbar toolbar; @ViewInject(R.id.refresh_view) private MaterialRefreshLayout refreshLayout; @ViewInject(R.id.hot_ware_list) private RecyclerView hotWareList; OkHttpHelper httpHelper = OkHttpHelper.getinstance(); private HotWaresListAdapter mAdapter; //用于記錄當(dāng)前是第幾頁(yè) private int curPage = 1; //用于記錄一頁(yè)應(yīng)該請(qǐng)求多少條數(shù)據(jù) private int pageSize = 10; //需要顯示的數(shù)據(jù) private List<Page.Ware> wareList; //用于記錄當(dāng)前是何種狀態(tài),在請(qǐng)求完數(shù)據(jù)之后根據(jù)不同的狀態(tài)進(jìn)行不同的操作 private static final int STATE_INIT = 0; private static final int STATE_REFRESH = 1; private static final int STATE_LOAD_MORE = 2; //用于記錄當(dāng)前的狀態(tài) private int curState = 0; //用于記錄總頁(yè)數(shù),在上拉的時(shí)候判斷還有沒(méi)有更多數(shù)據(jù) private int totalPage = 1; @Nullable @Override public View onCreateView(LayoutInflaterinflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_hot, container, false); ViewUtils.inject(this, view); initRefreshLayout(); getData(); return view; } private void initRefreshLayout() { //設(shè)置支持下拉加載更多 refreshLayout.setLoadMore(true); //刷新以及加載回調(diào) refreshLayout.setMaterialRefreshListener(new MaterialRefreshListener() { @Override public void onRefresh(MaterialRefreshLayout materialRefreshLayout) { //下拉刷新回調(diào),更改當(dāng)前狀態(tài)為下拉刷新?tīng)顟B(tài),把當(dāng)前頁(yè)置為第一頁(yè), //向服務(wù)器請(qǐng)求數(shù)據(jù) curState = STATE_REFRESH; curPage = 1; getData(); } @Override public void onRefreshLoadMore(MaterialRefreshLayoutmaterialRefreshLayout) { //上拉加載更多回調(diào),更改當(dāng)前狀態(tài)為上拉加載更多狀態(tài),頁(yè)數(shù)加1 //并且在判斷還有更多的情況下向服務(wù)器請(qǐng)求數(shù)據(jù) //否則提示用戶沒(méi)有更多數(shù)據(jù),關(guān)閉上拉加載更多 curState = STATE_LOAD_MORE; curPage = curPage + 1; if (curPage <= totalPage) { getData(); } else { Toast.makeText(getActivity(), "沒(méi)有更多啦O(∩_∩)O", Toast.LENGTH_SHORT).show(); refreshLayout.finishRefreshLoadMore(); } } }); } private void getData() { String uri = "http://112.124.22.238:8081/course_api/wares/hot?curPage=" + curPage + "&pageSize=" + pageSize; httpHelper.get(uri, newBaseCallback<Page>() { @Override public void onRequestBefore() { } @Override public void onFailure(Request request, Exception e) { } @Override public void onSuccess(Response response, Page page) { //得到數(shù)據(jù) wareList = page.getWareList(); //得到總頁(yè)數(shù),上拉加載更多的時(shí)候用于判斷還有沒(méi)有更多數(shù)據(jù) totalPage = page.getTotalPage(); showData(); } @Override public void onError(Response response, int errorCode, Exception e) { } }); } private void showData() { switch (curState) { case STATE_INIT: //初始化狀態(tài),初始化列表 mAdapter = newHotWaresListAdapter(wareList, getActivity()); hotWareList.setAdapter(mAdapter); hotWareList.setLayoutManager(new LinearLayoutManager(getActivity())); hotWareList.setItemAnimator(new DefaultItemAnimator()); break; case STATE_REFRESH: //下拉刷新?tīng)顟B(tài),刷新數(shù)據(jù),列表回到最頂端,關(guān)閉下拉刷新 mAdapter.refreshData(wareList); hotWareList.scrollToPosition(0); refreshLayout.finishRefresh(); break; case STATE_LOAD_MORE: //上拉加載更多狀態(tài),追加數(shù)據(jù),關(guān)閉上拉加載更多 mAdapter.loadMoreData(wareList); refreshLayout.finishRefreshLoadMore(); break; } } } 五、效果圖 好了今天的筆記到這里為止了,是不是感覺(jué)高大上有木有,O(∩_∩)O哈哈~!
|