RecyclerView提供了良好的设计,将各部分功能的实现都拆解开,方便自定义,虽然加大了使用难度,但是却大大的增加了可扩展性,稍微会使用之后,扩展起来非常的舒心。
功能:适用于以下几种布局的分割线和粘性头部
- LinearLayoutManager
- GridLayoutManager (水平方向粘性头部暂未实现)
- StaggeredGridLayoutManager (粘性头部暂未实现)
对于分割线,与大多数的实现不同,在GridLayoutManager和StaggeredGridLayoutManager布局时是平分Item的,分割线大的时候就能发现
先上效果图
注意:其中这三种布局的分割线不管是水平还是垂直方向都是支持的,但是带有header的只支持LinearLayoutManager的水平和垂直以及GridLayoutManager垂直方向
还可以下载Demo在手机上预览一下。
1、在根目录的build.gradle中加入如下配置
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
2、在要用的module中增加如下引用
dependencies {
...
implementation 'com.github.arvinljw:ItemDecorationHelper:v1.0.5'
implementation 'com.android.support:recyclerview-v7:'.concat(supportVersion)
}
其中supportVersion换成自己app中的版本即可
3、为RecyclerView添加ItemDecoration,通过ItemDecorationFactory生成包括分割线的ItemDecoration和粘性头部的ItemDecoration,后者包含了分割线
- ItemDecorationFactory.DividerBuilder 分割线
itemDecoration = new ItemDecorationFactory.DividerBuilder()
.dividerHeight(2)
.dividerColor(Color.parseColor("#D8D8D8"))
.showLastDivider(false)//默认是true
.build(recyclerView);
recyclerView.addItemDecoration(itemDecoration);
- ItemDecorationFactory.StickyDividerBuilder 粘性头部
itemDecoration = new ItemDecorationFactory.StickyDividerBuilder()
.dividerHeight(2)
.dividerColor(Color.parseColor("#D8D8D8"))
.callback(new StickyDividerCallback() {
@Override
public GroupData getGroupData(int position) {
//生成GroupData
return data;
}
@Override
public View getStickyHeaderView(int position) {
//...生成headerView
return headerView;
}
}).build(recyclerView);
recyclerView.addItemDecoration(itemDecoration);
其中如果是粘性头部,需要自己生成GroupData和自定义View的设置,GroupData需要设置,分组标题,在分组中的位置以及该分组的长度;至于如何实现,需要根据数据格式定义不同的逻辑,可以参照demo中的实现逻辑去获取,该类的getItemDecoration方法。
对于分割线没啥说的,可以设置分割线的颜色和大小。
其中对于显示分组头部,有一个默认实现DefaultHeaderCallBack,只需要重写分组数据即可。例如:
headerCallBack = new DefaultHeaderCallBack(this) {
@Override
public GroupData getGroupData(int position) {
//生成GroupData
return data;
}
};
注意如果添加在Adapter中添加了emptyView,那么这个时候其实是没有数据项的,所以在getGroupData方法中返回null即可
为头部增加点击事件,其中回调中的position是当前header所在的item的实际位置。
((BaseStickyDividerItemDecoration) itemDecoration).setOnHeaderClickListener(new OnHeaderClickListener() {
@Override
public void onHeaderClicked(int position) {
//TODO
}
});
注意:在界面被销毁时,调用headerCallBack的onDestroy方法,避免内存泄漏。
-keep class net.arvin.itemdecorationhelper.**{*;}
- 优化实现方式
继承ItemDecoration,然后重写getItemOffsets
和onDraw
方法,实现分割线的绘制,通过重写onDrawOver
实现粘性头部。
原理很简单,就是首先让itemView在你需要的方向偏移,例如left,top,right,botton;然后再在onDraw
或者onDrawOver
方法中获取到当前屏幕的view,并根据他们的位置,按照偏移的逻辑在相应区域绘制即可。借用一张图,感谢【Android】RecyclerView:打造悬浮效果。
很直观,可以看到不同内容绘制在不同层次,位置重合的话,上层会覆盖下层的内容。
具体的实现全是根据这个逻辑计算绘制。其中为了保持平分内容,将分割线拆分,如图:感谢RecyclerView的 GridItemDecoration等分itemView
具体的难点就在这两个位置。
至于粘性头部,核心逻辑就是对数据的分组以及头部的偏移计算和绘制。也是万变不离其中。具体的实现请参考源码,含有一定的注释。
RecyclerView 悬浮/粘性头部——StickyHeaderDecoration
RecyclerView的 GridItemDecoration等分itemView
在实现过程中参考了很多文章,如果没有注明来源的,麻烦指出来,会直接加上引用来源的。
Copyright 2018 arvinljw
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 IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.