Hello大家好,郭老司機又來了。以前都是看文章的小喵同志,如今終於體也會到碼字的不易,作為一個沉默寡言的程式猿,對於碼文無數的前輩深表敬佩((/- -)/。
這是歡迎各位踐踏的Github:github.com/CarGuo
我叫DEMO:github.com/CarGuo/Lazy…
RecylerView相信大家都聽過(你確定要說沒聽過 = =),在ListView橫行的年代裡,RecyclerView攜帶了褒貶不一的評價,開始進入了我們的視線,那時候剛好開始了新的專案,正好就拿它練手了。下方進入介紹使用流程,建議對著Demo擼起來。( ・᷄-・᷅ )
正常情況下,對於每一個不同的列表,我們經常需要實現不同的Adapter ,來處理對應的邏輯,這樣導致了我們有著許多重複的程式碼,在優化程式碼(懶)這種動力的驅動下,個人實現了一個通用的Adapter。後面所說的Holder,可以理解為列表中一個Item,屬於它的邏輯處理類,每一種型別的Item有一種Holder。
只需要一個Adapter,你就可以實現各種型別的列表,在一個列表裡相容不同型別的Item,你需要做的,僅僅是維護你的Holder(類似List裡的一個Item)和Model,無需再關心其他,實現高複用與多樣式邏輯,外帶支援自定義動畫,多種上下拉實現方式,不需要再寫任何Adapter程式碼(^o^)/。
1、 CommonRecyclerManager :繫結layoutId和你的Holder類名。
這個管理類是用於繫結Holder和R.layout.xxx,這樣在後面CommonRecyclerAdapter 用它通過資料Model的layoutId,找到對應的Holder並建立它。
//將佈局的ID和holder型別關聯
commonRecyclerManager.addType(TextHolder.ID, TextHolder.class.getName());複製程式碼
2、 RecyclerBaseHolder :繼承這個Holder,實現你的需求。
RecyclerBaseHolder的所有Holder的基類,他繼承了RecyclerView.ViewHolder,並定義寫兩個方法,所以你繼承它就對了,在createView的時候找到控制元件,在onBind讀取資料填充畫面。這裡就是實現你夢想的地方!
//實現的hodler繼承RecyclerBaseHolder,過載下面方式實現你的需求
public class TextHolder extends RecyclerBaseHolder {
//佈局id,一般我習慣吧這個Holder需要處理的id都寫在這裡,方便管理
public final static int ID = R.layout.text_item;
@BindView(R.id.item_text)
TextView itemText;
public TextHolder(Context context, View v) {
super(context, v);
}
//view建立好了
@Override
public void createView(View v) {
ButterKnife.bind(this, v);
}
//view建立好了,更具資料處理邏輯
@Override
public void onBind(RecyclerBaseModel model, int position) {
//轉化為你的model
TextModel textModel = (TextModel) (model);
itemText.setText(textModel.getText());
}
//不需要可以不寫
@Override
public AnimatorSet getAnimator(View view) {
//實現你的動畫
return null;
}
}複製程式碼
3、 CommonRecyclerAdapter :通用的介面卡
只需要傳入資料List和CommonRecyclerManager,就會根據Model的順序,通過資料的layoutId,在RecyclerView中自動生成對應的Holder,其他的功能只需要簡單的配置即可。
//用資料和manager建立
adapteradapter = new CommonRecyclerAdapter(getActivity(), commonRecyclerManager, datas);
//支援需要載入更多
adapter.setNeedLoadMore(true);
//支援空資料顯示 空頁面
adapter.setShowNoData(true);
//設定item顯示動畫支援開啟
adapter.setNeedAnimation(true);複製程式碼
4、RecyclerBaseModel :資料model的積累,必須繼承它,不離不棄。
繼承它的作用是,因為整個Adapter都是以它為基類,你需要繼承他,最終的是,你需要這個Model對應的佈局Id,這樣它才能找到屬於自己的Holder。
//繼承RecyclerBaseModel實現你需要的資料型別
public class TextModel extends RecyclerBaseModel {
private String text = "";
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}複製程式碼
總結起來就是
1、實現你的Holder並繼承RecyclerBaseHolder,這裡是你實現需求的地方,相當於Item的邏輯。
2、讓你的資料model繼承RecyclerBaseModel,設定Model的LayoutId(很重要),這樣model就會通過CommonRecyclerManager,找到LayoutId對應關聯的Holder,並生成它。
3、你需要一個CommonRecyclerManager來繫結你的LayoutId和處理這佈局的Holder類名。
4、通過CommonRecyclerManager和Model的資料列表生成CommonRecyclerAdapter。
5、把Adapter交給Recycler。
邏輯看起來是不是有些複雜?其實就是model的LayoutId,CommonRecyclerManager通過關聯了處理它的Holder。這樣我們只需要在資料List裡,根據資料設定不同的LayoutId的model,Adapter就會自動匹配對應的Holder。
如此一來,<( ̄︶ ̄)>你只需要實現好Holder和組裝好Model,任何列表都可以使用起來,不需要再寫Adapter邏輯了。根據model的順序,Adapter自動生成對應的Holder,並且同一個Holder是可以繫結不同的LayoutId,以後你只需要維護和相容你的Holder,在各個列表裡通用的你holder邏輯了,是不是瞬間程式碼乾淨了好多?
下拉重新整理與上拉載入更多
普通的列表,直接使用系統的SwipeRefreshLayout就可以啦,簡單有好用。下拉載入更多直接新增下方方法,輕鬆實現上下拉重新整理<( ̄︶ ̄),簡單粗暴,就是記得要加個鎖避免重複進入。
//開啟支援需要載入更多
adapter.setNeedLoadMore(true);
recycler.addOnScrollListener(new LoadMoreScrollListener() {
@Override
public void onLoadMore() {
//注意加鎖
if (!isLoadMore) {
isLoadMore = true;
recycler.postDelayed(new Runnable() {
@Override
public void run() {
isLoadMore = false;
loadMore();
}
}, 2000);
}
}
//當前第一個可視的是哪個item
@Override
public void onScrolled(int firstPosition) {
}
});複製程式碼
其他配置
你還可以配置是否顯示動畫效果,配置上拉loading的顏色,單擊和長按等,看下面。
//支援空資料顯示 空頁面
adapter.setShowNoData(true);
//顯示空資料model,不設定顯示預設空頁面
adapter.setNoDataModel(noDataModel);
//顯示空資料頁面佈局,不設定顯示預設,佈局id需要通過CommonRecyclerManager關聯hodler
adapter.setNoDataLayoutId(noDataLayoutId);
//設定動畫支援開啟
adapter.setNeedAnimation(true);
//新增點選
adapter.setOnItemClickListener();複製程式碼
XRecyclerView相容支援
這裡新增了XRecyclerView,並且對其進行了修改。XRecyclerView內建了內部Adapter,使其支援新增頭部,自帶上下拉效果的控制元件,部分調整之後,全面支援CommonRecyclerAdapter。
不需要監聽滑動,不需要SwipeRefreshLayout,輕鬆新增重新整理與載入更多。而且更是支援動態配置,上下拉的各種樣式支援,具體在ProgressStyle下有多種型別支援配置,解決了Adapter對瀑布流上拉的支援不夠相容的問題。
這裡使用方式,和普通的RecyclerView一樣,支援和CommonRecyclerAdapter的配合,而且它同樣支援空頁面顯示,還支援新增各種頭部,唯一需要注意的是,新增分割線類addItemDecoration和點選的時候,需要針對新增了頭部,和重新整理的絕對的position,換算成相對的位置,此處曾經把自己坑哭了╥﹏╥...,下面看程式碼吧。
//是否遮蔽下拉
//xRecycler.setPullRefreshEnabled(false);
//上拉載入更多樣式,也可以設定下拉
xRecycler.setLoadingMoreProgressStyle(ProgressStyle.SysProgress);
//設定管理器,關聯佈局與holder類名,不同id可以管理一個holder
CommonRecyclerManager commonRecyclerManager = new CommonRecyclerManager();
commonRecyclerManager.addType(ImageHolder.ID, ImageHolder.class.getName());
commonRecyclerManager.addType(TextHolder.ID, TextHolder.class.getName());
commonRecyclerManager.addType(ClickHolder.ID, ClickHolder.class.getName());
//初始化通用管理器
commonRecyclerAdapter = new CommonRecyclerAdapter(getActivity(), commonRecyclerManager, dataList);
xRecycler.setAdapter(commonRecyclerAdapter);
ImageView imageView = new ImageView(getActivity());
imageView.setImageResource(R.drawable.xxx1);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setMinimumHeight(dip2px(getActivity(), 100));
//新增頭部
xRecycler.addHeaderView(imageView);
//本身也支援設定空區域性
//xRecycler.setEmptyView();
xRecycler.setLoadingListener(new XRecyclerView.LoadingListener() {
@Override
public void onRefresh() {
xRecycler.postDelayed(new Runnable() {
@Override
public void run() {
xRecycler.refreshComplete();
}
}, 2000);
}
@Override
public void onLoadMore() {
xRecycler.postDelayed(new Runnable() {
@Override
public void run() {
loadMore();
}
}, 2000);
}
});
commonRecyclerAdapter.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(Context context, int position) {
//需要減去你的header和重新整理的view的數量
Toast.makeText(getActivity(), "點選了!! " + (position - 2), Toast.LENGTH_SHORT).show();
}
});複製程式碼
最後
到這裡你已經知道了大致的用法了吧。詳細的內部實現,可以通過DEMO檢視。大致邏輯是 CommonRecyclerManager 關聯接layoutId和Holder類名,CommonRecyclerAdapter通過Model的layoutId找到這個Holder,然後用layoutId建立view,把View、position、model傳入到Holder裡面實現資料填充。所layoutId也是*型別id,注意:
使用的時候切記要給你的model設定setResLayoutId(),這是最容易讓人遺忘的。
我叫DEMO:github.com/CarGuo/Lazy…