Android開發操做案例分享!android
Android LRecyclerView 操做案例分享-實現下拉刷新、滑動到底部自動加載,一直想抽空寫下這個開源項目www.lampbrother.net,可是各類緣由沒有抽時間,今天仍是趁着工做間隙寫下了這篇博客,與你們分享。git
簡介github
LRecyclerView是支持addHeaderView、 addFooterView、下拉刷新、分頁加載數據的RecyclerView。網絡
它對 RecyclerView 控件進行了拓展,給RecyclerView增長HeaderView、FooterView,而且不須要對你的Adapter作任何修改。maven
主要功能ide
下拉刷新、滑動到底部自動加載下頁數據;佈局
能夠方便添加Header和Footer;gradle
頭部下拉樣式能夠自定義;ui
具有item點擊和長按事件。this
網絡錯誤加載失敗點擊Footer從新請求數據;
能夠動態爲FooterView賦予不一樣狀態(加載中、加載失敗、滑到最底等)。
感謝
若是我比別人看得遠些,那是由於我站在巨人們的肩上。 (牛頓)
本開源控件是基於 HeaderAndFooterRecyclerView 開源項目而來,在原基礎上進行了擴充。在此感謝兄弟連教育(www.lampbrother.net)的分享
Gradle
Step 1. 在你的根build.gradle文件中增長JitPack倉庫依賴。
allprojects {
repositories {
jcenter()
maven { url "https://jitpack.io" }
}
}
Step 2. 在你的model的build.gradle文件中增長LRecyclerView依賴。
compile 'com.github.jdsjlzx:LRecyclerView:1.0.0'
使用
添加HeaderView、FooterView
mDataAdapter = new DataAdapter(this);
mDataAdapter.setData(dataList);
mHeaderAndFooterRecyclerViewAdapter = new HeaderAndFooterRecyclerViewAdapter(this, mDataAdapter);
mRecyclerView.setAdapter(mHeaderAndFooterRecyclerViewAdapter);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
//add a HeaderView
RecyclerViewUtils.setHeaderView(mRecyclerView, new SampleHeader(this));
//add a FooterView
RecyclerViewUtils.setFooterView(mRecyclerView, new SampleFooter(this));
注意:
mHeaderAndFooterRecyclerViewAdapter = new HeaderAndFooterRecyclerViewAdapter(this, mDataAdapter);
HeaderAndFooterRecyclerViewAdapter提供了一些實用的功能,使用者不用關心它的實現,只需構造的時候把本身的mDataAdapter以參數形式傳進去便可。
下拉刷新和加載更多
爲了你們使用方便,將須要用的方法統一封裝到接口LScrollListener中。
mRecyclerView.setLScrollListener(new LRecyclerView.LScrollListener() {
@Override
public void onRefresh() {
}
@Override
public void onScrollUp() {
}
@Override
public void onScrollDown() {
}
@Override
public void onBottom() {
}
@Override
public void onScrolled(int distanceX, int distanceY) {
}
});
LScrollListener實現了nRefresh()、onScrollUp()、onScrollDown()、onBottom()、onScrolled五個事件,以下所示:
void onRefresh();//pull down to refresh
void onScrollUp();//scroll down to up
void onScrollDown();//scroll from up to down
void onBottom();//load next page
void onScrolled(int distanceX, int distanceY);// moving state,you can get the move distance
onRefresh()——RecyclerView下拉刷新事件;
onScrollUp()——RecyclerView向上滑動的監聽事件;
onScrollDown()——RecyclerView向下滑動的監聽事件;
onBottom()——RecyclerView滑動到底部的監聽事件;
onScrollDown()——RecyclerView正在滾動的監聽事件;
加載更多(加載下頁數據)
從上面的LScrollListener介紹中就能夠看出,實現加載更多隻要在onBottom()接口中處理便可。
下拉刷新
爲了達到和Listview的下拉刷新效果,本項目沒有藉助SwipeRefreshLayout控件,而是在自定義RecyclerView頭部實現的刷新效果。
這裏的下拉刷新效果借鑑了開源庫:AVLoadingIndicatorView
mRecyclerView.setRefreshProgressStyle(ProgressStyle.BallSpinFadeLoader);
mRecyclerView.setArrowImageView(R.drawable.iconfont_downgrey);
AVLoadingIndicatorView庫有多少效果,LRecyclerView就支持多少下拉刷新效果,固然你也能夠自定義下拉效果。
下拉刷新邏輯處理:
從上面的LScrollListener介紹中就能夠看出,實現下拉刷新只要在onRefresh()接口中處理便可。
加載網絡異常處理
加載數據時若是網絡異常或者斷網,LRecyclerView爲你提供了從新加載的機制。
網絡異常出錯代碼處理以下:
RecyclerViewStateUtils.setFooterViewState(getActivity(), mRecyclerView, getPageSize(), LoadingFooter.State.NetWorkError, mFooterClick);
private View.OnClickListener mFooterClick = new View.OnClickListener() {
@Override
public void onClick(View v) {
RecyclerViewStateUtils.setFooterViewState(getActivity(), mRecyclerView, getPageSize(), LoadingFooter.State.Loading, null);
requestData();
}
};
上面的mFooterClick就是咱們點擊底部的Footer時的邏輯處理事件,很顯然咱們仍是在這裏作從新請求數據操做。
點擊事件和長按事件處理
在Hongyang前輩的博客中有下描述:
Click and LongClick
不過一個挺鬱悶的地方就是,系統沒有提供ClickListener和LongClickListener。
不過咱們也能夠本身去添加,只是會多了些代碼而已。
實現的方式比較多,你能夠經過mRecyclerView.addOnItemTouchListener去監聽而後去判斷手勢, 固然你也能夠經過adapter中本身去提供回調,這裏咱們選擇後者,前者的方式,你們有興趣本身去實現。
Hongyang大神選擇了後者,LRecyclerView早期選擇了前者,通過實踐總結,在adapter中實現點擊事件會好點。
先看下怎麼使用:
mHeaderAndFooterRecyclerViewAdapter.setOnItemClickLitener(new OnItemClickLitener() {
@Override
public void onItemClick(View view, int position) {
}
@Override
public void onItemLongClick(View view, int position) {
}
});
原理就是實現viewHolder.itemView的點擊和長按事件。因爲代碼過多就不貼出來了。
viewHolder.itemView是RecyclerView.Adapter中自己就具備的,不用額外定義。
源碼以下:
public static abstract class ViewHolder {
public final View itemView;
int mPosition = NO_POSITION;
int mOldPosition = NO_POSITION;
long mItemId = NO_ID;
int mItemViewType = INVALID_TYPE;
int mPreLayoutPosition = NO_POSITION;
設置空白View(setEmptyView)
mRecyclerView.setEmptyView(view);
注意佈局文件:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<com.cundong.recyclerview.LRecyclerView
android:id="@+id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
<include
android:id="@+id/empty_view"
layout="@layout/layout_empty"
android:visibility="gone"/>
</RelativeLayout>
分享
介紹完了LRecyclerView,彷佛還少些什麼,對了,那就是adapter了。
爲了方便你們使用,分享個封裝過的adapter。
public class ListBaseAdapter<T extends Entity> extends RecyclerView.Adapter {
protected Context mContext;
protected int mScreenWidth;
public void setScreenWidth(int width) {
mScreenWidth = width;
}
protected ArrayList<T> mDataList = new ArrayList<>();
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return null;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
}
@Override
public int getItemCount() {
return mDataList.size();
}
public List<T> getDataList() {
return mDataList;
}
public void setDataList(Collection<T> list) {
this.mDataList.clear();
this.mDataList.addAll(list);
notifyDataSetChanged();
}
public void addAll(Collection<T> list) {
int lastIndex = this.mDataList.size();
if (this.mDataList.addAll(list)) {
notifyItemRangeInserted(lastIndex, list.size());
}
}
public void clear() {
mDataList.clear();
notifyDataSetChanged();
}
}
ListBaseAdapter使用了泛型,簡單方便,消除了強制類型轉換。
使用以下:
private class DataAdapter extends ListBaseAdapter<ItemModel>{
private LayoutInflater mLayoutInflater;
public DataAdapter(Context context) {
mLayoutInflater = LayoutInflater.from(context);
mContext = context;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new ViewHolder(mLayoutInflater.inflate(R.layout.sample_item_text, parent, false));
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
ItemModel item = mDataList.get(position);
ViewHolder viewHolder = (ViewHolder) holder;
viewHolder.textView.setText(item.title);
}
private class ViewHolder extends RecyclerView.ViewHolder {
private TextView textView;
public ViewHolder(View itemView) {
super(itemView);
textView = (TextView) itemView.findViewById(R.id.info_text);
}
}
}
ListBaseAdapter雖然功能不強大,可是使用很方便。
結語
LRecyclerView使用方便簡單,不管你添加多少Header和Footer,你都不用擔憂position的問題,除了方便仍是方便。你們用起來吧!