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~! :)
或者有什么意见和建议的可以私信我,后面的版本中做些完善~