RecyclerView
已經出來很久了.由于是Google推崇的新列表控件,所以開發者重心漸漸偏移到這個上面.可是在對比ListView的情況下,發現還是很多ListView
原有比較好用的API在RecyclerView中沒有提供,比如addHeaderView
,addFooterView
,setEmptyView
等等.
于是為了開發便利,不少大神寫了很好的開源庫,比如Hongyang的baseAdapter,CymChad的BaseRecyclerViewAdapterHelper.其中前者在處理header,footer,loading布局的時候是采用裝飾著模式,在適配器外面包裹了一層,這樣處理不會影響原來原來適配器的位置.后者是將這些布局作為條目布局來寫.
然后在開發中,經常遇到有checkable條目的需求.ListView
中有setChoiceMode
這樣好用的API,RecyclerView
卻沒有.于是受以上提及庫的啟發,開發了此庫.
一個通用的RecyclerView的Adapter basic-adapter,主要支持:
- 添加頭,尾布局
- 預加載更多
- 支持單、多選條目(同ListView的ChoiceMode)
- 支持空數據布局
- Builder mode 鏈式初始化配置
- 添加條目點擊事件(普通條目,不包括頭尾)
下載
通過 Maven:
<dependency>
<groupId>com.lhalcyon</groupId>
<artifactId>basic-adapter</artifactId>
<version>1.0.1</version>
<type>pom</type>
</dependency>
或 Gradle:
compile 'com.lhalcyon:basic-adapter:1.0.1'
用法:
初始化適配器:
BasicParams p = new BasicController.Builder()
.layoutRes(R.layout.item)//普通條目布局 ,必要屬性
.build();
mRecyclerView.setAdapter(mAdapter = new MyAdapter(p,list));
可選的配置如下:
BasicParams p = new BasicController.Builder()
.layoutRes(R.layout.item)
.header(header)
.header(header2)
.footer(footer)
.empty(empty)
.loaded(loaded)//沒有更多數據 布局
.loading(loading)//上拉加載 布局
.onLoadMore(new OnLoadMoreListener() {//加載更多監聽(注意線程)
@Override
public void onLoad() {
//加載更多
}
})
.build();

單/多選 條目配置
BasicParams params = new BasicController.Builder()
.checkId(R.id.checkbox)//checkable 控件 id, 目前只支持條目id唯一
.choiceMode(BasicController.CHOICE_MODE_MULTIPLE)//選擇模式 單選,多,無
.layoutRes(R.layout.item_check)
.build();
再復寫方法 isItemChecked(T t,int position)
和設置 OnItemClickListener
,這兩部不能省略
mRecyclerView.setAdapter(mAdapter = new CheckAdapter(params,mManList){
@Override
public boolean isItemChecked(Man man, int position) {
return man.isSingle;
//必復寫的方法,用來初始化條目選擇狀態,如果適配器為單選,此方法卻有多個條目返回true,則只有最后一個返回true的條目是選中的.
}
});
mAdapter.setOnItemClickListener(mRecyclerView, new OnItemClickListener() {
@Override
public void onItemClick(BaseViewHolder vh, int position) {
//單擊條目事件,必須設置,內容可空
}
});
單選模式:

多選模式:

gif效果比較差 :( , 在真機以及模擬器上效果不錯.
本庫采用的是BaseRecyclerViewAdapterHelper 的思路,將header,footer,loading等布局做成條目布局.而細節上又有所不同.原庫位置是根據不同條件做了很多判斷,比較復雜.本庫將這些布局做了相應的固定,假設List<T> mData
為數據集合:
布局 | 條件 | 位置 | 備注 |
---|---|---|---|
Header | 常駐 | 0 | headers的容器(LinearLayout) |
Empty | mData.size()==0 | 1 | 根據數據集合大小判斷 |
Normal | 有數據時顯示 | [1,mData.size()] | 和Empty同時只有一類存在 |
Load | 常駐 | mData.size() + 1 + empty | 加載中loading/沒有更多數據loaded容器 |
Footer | 常駐 | mData.size() + 2 + empty | footers的容器(LinearLayout) |
int empty = mData.size() == 0 ? 1 : 0;
Header,Footer,Load都是常駐的,均為高度wrap_content
的LinearLayout
.因此不需要做復雜的邏輯判斷,沒有配置這些條目的時候因為是wrap_content
所以均不顯示.
需要注意的是,由于Load布局是作為一個條目布局,因此有個預加載的效果,即此條目可見的時候便出發了加載更多的監聽.如果當前頁面數據條目加上加載更多請求回來的數據條目還不到一個屏幕的話,會接連觸發第二次加載更多,造成不好的體驗.因此在UI條目高度較小,或者請求
PageSize
較小時慎用.
單/多選 配置以及效果上面已經介紹過了.具體代碼可以參考sample里面的.
需要注意的是,在choice mode為single的時候,內部是改變了所有item的check state,然后調用notifyDataSetChange(),此時UI上如果是Material Design的Checkbox便不會有動畫的渲染便直接選中.此處若有解決思路或者辦法,希望一起討論下.
GitHub地址basic-adapter 希望能給個star~! :)
或者有什么意見和建議的可以私信我,后面的版本中做些完善~