MultiType-Adapter
一款轻量级支持多数据类型的 RecyclerView 适配器; 使用简单,完全解耦;
这么说吧:通讯聊天界面、朋友圈布局、淘宝 UI等复杂页面 优雅快速实现,无论你是一种数据有多种VIew类型,还是多种数据多种类型,还是两者都有,统统帮你快速地、优雅地搞定!
代码传送门
·总览
·特性
· 基础用法
· 单数据
· 多数据-多类型
· 单类型-多数据
· 事件
·高级用法
· 网格布局与线性布局混合编排
· 瀑布流布局
· 上拉加载
· 无数据时过度界面设置
· 混合布局拖拽实现
· 悬浮吸顶效果
· 设置复用数量
·扩展
·Thrank
`一些说明
总览
总体来讲支持以下效果
特性
· 轻盈、整个类库只有9个文件
· 全面、支持 bean type 之间 一对一 和 一对多 的关系绑定
· 职责单一、只负责本分工作,专注多类型的列表视图 类型分发,不会影响 view 的内容或行为
· 内存、没有性能损失,内存友好
· 可读、代码清晰干净
基础用法
// root build.gradle
repositories {
jcenter()
maven { url "https://www.jitpack.io" }
}
// yout project build.gradle
dependencies {
compile 'com.github.LidongWen:MultiTypeAdapter:0.2.6'
}
单数据
CommonAdapter adapter = new CommonAdapter<ItemClass>(this, ItemClass.class, R.layout.item_one) {
@Override
protected void convert(ViewHolder holder, final ItemClass item, int position) {
holder.setText(R.id.tv_item01, item.name);
}
};
....
recyclerView.setAdapter(adapter);
示例查看:single example
多数据-多类型
一个数据类型对应一种viewType
创建一个或多个 class
继承MultiItemView
,这边做某一种数据类型 对应的 ItemView
的创建,与数据装配
public class ItemVIew01 extends MultiItemView<Bean01> {
@NonNull
@Override
public int getLayoutId() {
return R.layout.item_one;
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, @NonNull Bean01 item, int position) {
holder.setText(R.id.tv_item01,item.title);
}
}
public class Item ...
创建一个 适配器MultiTypeAdapter
,注册 bean
与 MultiItemView
将适配器设入RecyclerView
;
private MultiTypeAdapter adapter = new MultiTypeAdapter();
adapter.register(Bean01.class, new ItemVIew01());
adapter.register(Bean02.class, new ItemVIew02());
adapter.register(Bean03.class, new ItemVIew03());
...
adapter.setItems(items);
recyclerView.setAdapter(adapter);
示例查看:many2many Example
单数据-多类型
一种数据类型可以有多种ViewType
创建一个或多个 class
继承MultiItemView
,其中 他们的数据类型要一致,重写 isForViewType
方法
public class ItemVIew04 extends MultiItemView<Bean04> {
...
@Override
public boolean isForViewType(Bean04 item, int postion) {
if (Bean04.TYPE_ONE.equals(item.type)) {
return true;
}
return false;
}
}
public class ItemVIew05 extends MultiItemView<Bean04> {
...
@Override
public boolean isForViewType(Bean04 item, int postion) {
if (Bean04.TYPE_TWO.equals(item.type)) {
return true;
}
return false;
}
}
创建一个入口 class
继承MultiItemView
, 构造函数时调用 addChildeItemView
方法
public class ItemVIew06 extends MultiItemView<Bean04> {
public ItemVIew06() {
super();
addChildeItemView(new ItemVIew04());
addChildeItemView(new ItemVIew05());
addChildeItemView(new ItemVIew07());
}
}
activity
adapter = new MultiTypeAdapter();
adapter.register(Bean04.class, new ItemVIew06());
...
示例查看:one-many Example
事件
设置点击事件于长按事件
adapter.setOnItemClickListener(new OnItemClickListener<ItemClass>() {
@Override
public void onItemClick(View view, RecyclerView.ViewHolder holder, ItemClass itemClass, int position) {
}
@Override
public boolean onItemLongClick(View view, RecyclerView.ViewHolder holder, ItemClass itemClass, int position) {
return false;
}
});
高级用法
网格布局与线性布局混合编排
根据数据类型设置 view 比重
adapter.register(String.class, new ItemVIewNormal()); // 一对一
adapter.register(Bean01.class, new ItemVIew01());
adapter.register(Bean02.class, new ItemVIew02());
adapter.register(Bean03.class, new ItemVIew03());
adapter.register(Bean04.class, new ItemVIew06()); // 一对多
final GridLayoutManager layoutManager = new GridLayoutManager(this, SPAN_COUNT);
GridLayoutManager.SpanSizeLookup spanSizeLookup = new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
Object item = items.get(position);
if (item instanceof Bean01) {
return 1;
}
if (item instanceof Bean02) {
return 2;
}
if (item instanceof Bean03) {
return SPAN_COUNT;
}
if (item instanceof Bean04 ) {
return SPAN_COUNT;
}
if (item instanceof String) {
return SPAN_COUNT;
}
return 2;
}
};
示例查看:mix Example
瀑布流布局
示例查看:WaterFall Example
上拉加载
效果如下
将我们的 初始化LoadMoreWrapper2
,添加上拉UI
LoadMoreWrapper2 loadMoreWrapper2;
private MultiTypeAdapter adapter;
loadMoreWrapper2 = new LoadMoreWrapper2(adapter);
loadMoreWrapper2.setLoadMoreView(LayoutInflater.from(this).inflate(R.layout.default_loading, recyclerView, false));
recyclerView.setAdapter(loadMoreWrapper2);
loadMoreWrapper2.setOnLoadMoreListener(new LoadMoreWrapper2.OnLoadMoreListener() {
@Override
public void onLoadMoreRequested() {
loadMoreWrapper2.loadingComplete();//加载完毕
}
});
// loadMoreWrapper2.setLoadMore(false); 开启或关闭加载功能
示例查看:pull-load Example
无数据时过度界面设置
EmptyWrapper emptyWrapper;
private MultiTypeAdapter adapter;
emptyWrapper = new EmptyWrapper(adapter);
emptyWrapper.setEmptyView(R.layout.layout_empty);
recyclerView.setAdapter(emptyWrapper);
示例查看:Empty Example
混合布局拖拽实现
吸顶效果
快速打造RecyclerView悬浮吸顶效果
一共有四种模式 请具体查看文章
设置复用数量
业务需要,设置每种view的最大复用数量
public class ItemVIew01 extends MultiItemView<Bean01> {
public void getMaxRecycleCount(){
return 5;
}
}
扩展
SasukeRecyclerView:基于MultiType-Adapter开发的一框下拉刷新上拉加载的库
Thrank
一些说明
大家可能咋一看,会认为我抄袭 drakeet的代码,我虽然有学习过他的代码,其中也让我受益良多,不论是技术点还是架构松耦合方面的知识,但是,这份开源库虽然使用上与之相似,但完全手写,不存在抄袭 drakeet , 而且 是否抄袭 请大家阅读完源码之后再做评论,谢谢。
V 0.2.6 ·增加黏贴布局类型
V 0.2.5 ·GroupWrapper支持放入其他包中
V 0.2.0 ·分组伸展收缩功能
V 0.1.4
·悬浮吸顶效果增强:可随意搭配itemVIew为悬浮布局
·事件处理优化
V 0.1.3
·检测并修复切换悬浮头部状态时发生内存泄漏;
V 0.1.2
·支持悬浮头部触摸事件,点击事件,长按事件等
·multiTypeAdapter支持restful风格调用
V 0.1.1
·MultiItemView 改变,更加简洁、直观
·新增 悬浮吸顶头部功能 快速打造Recyclerview悬浮吸顶头部
V 0.1.1
·支持头部吸顶功能
V 0.0.1
·实现一对一关系功能
·实现一对多关系功能
·事件监听
·支持网格、瀑布流、线性布局
·上拉加载功能
·数据为空时过渡界面展示功能
代码传送门:戳我!!!
来上一张架构图
希望我的文章不会误导在观看的你,如果有异议的地方欢迎讨论和指正。
如果能给观看的你带来收获,那就是最好不过了。