SherlockAdapter
一个万能的封装了RecyclerView.Adapter的功能库。
Install / Use
/learn @EvilBT/SherlockAdapterREADME
SherlockAdapter
新增功能
- 2019-10-12 更加方便的文本设置方法
- 2019-08-09 支持AndroidX
- 2017-04-26 添加控制头部尾部在瀑布流或者网格布局时横跨布局的开关及spanSize的大小
- 2017-04-13 添加保持显示头部尾部开关,在显示Error布局或者Empty布局时也能选择显示头部与尾部功能
- 2017-04-12 添加DiffUtil支持,添加StaggeredGridLayout的混合布局实现
- 2017-03-12 添加关闭子展开项上的所有已经可见的子项,即关闭当前展开项所有子项
- 2017-01-22 新添加支持多选item,可实现例如选择多张图片的功能
一个封装了RecyclerView.Adapter一些常用功能的库。
封装的功能
- item 的点击事件
- item 的长按事件
- item 的子View对应的点击事件
- item 的子View对应的长按事件
- 自动加载更多功能,内置一个基础的加载更多界面,如果有需要,可以自定义界面
- Empty界面,已经内置了一个基础的Empty界面,如果有需要,可以自定义界面
- Failed界面,已经内置了一个基础的Failed界面,如果有需要,可以自定义界面
- 支持添加任意数量的HeadLayout
- 支持添加任意数量的FootLayout
- 支持多布局数据界面
- 支持伸缩子项,理论上无层次限制
- 新添加支持多选item,可实现例如选择多张图片的功能
注意事项
先说注意事项,一般来讲,由于SherlockAdapter采用LayoutRes的值来作为ItemViewType返回,而ItemViewType是用来区分不同的Item的,所以如果不是同种Item,就不要使用同一个Layout文件,例如头部HeadLayout跟ItemLayout的布局是一样的情况下,就复制多一个Layout出来就行,不要共用一个Layout。
兼容性
- 最低的Android SDK: SherlockAdapter 2.0.0 要求最低API级别为14.
开始配置
Step 1. Add the dependency
dependencies {
implementation 'xyz.zpayh:sherlockadapter:2.0.3'
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.recyclerview:recyclerview:1.0.0'
}
新增功能使用方法
控制头部尾部横跨布局
通过以下代码控制头部尾部布局,详情及效果请参考Demo中的BasicActivity:
public class AutoLoadMoreActivity extends AppCompatActivity {
//...
@Override
protected void onCreate(Bundle savedInstanceState) {
//...
mAdapter.addHeadLayout(R.layout.item_head,fullSpan);
// Or
// 在Grid布局时,如果spanSize <= 0的话,会根据fullSpan的值去设置返回的spanSize
// 大小,如果fullSpan为true,则返回spanCount,如果为false,则返回 1.
mAdapter.addHeadLayout(R.layout.item_head1,fullSpan,spanSize);
mAdapter.addFootLayout(R.layout.item_foot,fullSpan);
// Or
mAdapter.addFootLayout(R.layout.item_foot,fullSpan,spanSize);
}
}
添加保持显示头部尾部开关
通过以下代码控制显示头部尾部开关,详情及效果请参考Demo中的AutoLoadMoreActivity:
public class AutoLoadMoreActivity extends AppCompatActivity {
//...
@Override
protected void onCreate(Bundle savedInstanceState) {
//...
mAdapter.setAlwaysShowHead(true);
mAdapter.setAlwaysShowFoot(true);
}
}
添加DiffUtil支持
具体代码如下,详情参考Demo中的ExpandableActivity:
public class ExpandableActivity extends AppCompatActivity {
// ......
private void initView() {
// ......
mAdapter.setCallback(new DiffUtilCallback<IMultiItem>() {
@Override
public boolean areItemsTheSame(IMultiItem oldItem, IMultiItem newItem) {
//判断是否为同一条数据 是就返回true,否则返回false。
if (oldItem instanceof ImageLabel && newItem instanceof ImageLabel){
return TextUtils.equals(((ImageLabel) oldItem).getData(),
((ImageLabel) newItem).getData());
}
if (oldItem instanceof Card && newItem instanceof Card){
return ((Card) oldItem).getData().mImageResId == ((Card) newItem).getData().mImageResId;
}
return false;
}
@Override
public boolean areContentsTheSame(IMultiItem oldItem, IMultiItem newItem) {
//当上面的 areItemsTheSame 返回ture是会进一步调用此方法,进一步确定
//同一条数据的内容是否发生变化
if (oldItem instanceof ImageLabel && newItem instanceof ImageLabel){
return true;
}
if (oldItem instanceof Card && newItem instanceof Card){
return TextUtils.equals(((Card) oldItem).getData().mImageTitle,
((Card) newItem).getData().mImageTitle);
}
return false;
}
});
}
}
效果:

使用方法
一般用法,继承BaseAdapter<T>实现三个抽象方法即可:
public abstract class BaseAdapter<T> extends RecyclerView.Adapter<BaseViewHolder>{
\\....
/**
* 返回布局layout
*/
@LayoutRes
public abstract int getLayoutRes(int index);
/**
* 在这里设置显示
*/
public abstract void convert(BaseViewHolder holder, T data, int index);
/**
* 开启子view的点击事件,或者其他监听
*/
public abstract void bind(BaseViewHolder holder,int layoutRes);
}
添加头部HeadLayout
adapter.addHeadLayout(R.layout.item_head);
然后在 convertHead 里控制显示。
public class HeadAndFootAdapter extends BaseAdapter<String> {
@Override
public void convertHead(BaseViewHolder holder, @LayoutRes int headLayout, int index) {
holder.setText(R.id.tv_head,"This is Head Layout");
}
}
![]()
添加尾部FootLayout
adapter.addFootLayout(R.layout.item_foot);
然后在 convertFoot 里控制显示。
public class HeadAndFootAdapter extends BaseAdapter<String> {
@Override
public void convertFoot(BaseViewHolder holder, @LayoutRes int footLayout, int index) {
holder.setText(R.id.tv_foot,"This is Foot Layout");
}
}
![]()
设置点击事件
在bind(BaseViewHolder holder,int layoutRes)里调用holder.setClickable(ID,true);启用item的子view的点击事件,并设置一下BaseAdapter.setOnItemClickListener()就可以了,详情参考MainActivity里的Adapter。如果只设置了点击事件,没有启用子view的点击,则是itemView响应消息。
设置长按事件
在bind(BaseViewHolder holder,int layoutRes)里调用holder.setLongClickable(ID,true);启用item的子view的长按事件,并设置一下BaseAdapter.setOnItemLongClickListener()就可以了,如果只设置了点击事件,没有启用子view的点击,则是itemView响应消息。基本使用方法与点击事件类似,具体参考Demo中的MultiItemActivity.
开启自动加载更多功能
参考 AutoLoadMoreActivity 的代码:
//必须设置事件监听与开启auto
mAdapter.openAutoLoadMore(true);
mAdapter.setOnLoadMoreListener(new OnLoadMoreListener() {
@Override
public void onLoadMore() {
//TODO Do something
}
});
![]()
支持多布局
如果布局管理器是GridLayoutManager,则简单继承BaseMultiAdapter抽象类,数据类型实现IMultiItem接口(可以简单继承DefaultMultiItem)即可。如果是StaggeredGridLayoutManager,则需要再实现IFullSpan接口,
具体参考Demo中的MultiItemActivity
![]()
支持伸缩子项
继承BaseExpandableAdapter,如果有可子项需要伸缩,数据类型实现IExpandable(可以简单继承DefaultExpandable),子项数据类型实现IMultiItem,如果
没有子项可伸缩,则数据类型实现IMultiItem即可,如果子项也有它的子项,则子项也需要实现IExpandable,子项的子项数据类型
实现IMultiItem接口。详情参考Demo中的ExpandableActivity

多选列表
继承BaseMultiSelectAdapter,数据类型实现IMultiSelectItem接口(可以简单继承DefaultMultiSelectItem)即可,具体可以参考Demo中MultiSelectItemActivity的实现方式。
![]()
更多细节请下载Demo查看源代码。
License
Copyright 2016 陈志鹏
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS
