本文介绍了 Android RecyclerView 悬浮效果,具体如下:
- 利用RecyclerView.ItemDecoration绘制Province(就像绘制分割线一样)
- 同一组的City,只绘制一个Province
- 计算偏移,将当前Province固定在顶部
- 根据列表滑动,实现偏移效果
1. 定义一个接口,根据 position 通过接口方法 getGroupName 获取当前省名(由Activity实现)
public interface GroupListener {
String getGroupName(int position);
}
2. 创建 BaseDecoration 继承 RecyclerView.ItemDecoration
public abstract class BaseDecoration extends RecyclerView.ItemDecoration {
/**
* group背景色,默认透明
*/
@ColorInt
int mGroupBackground = Color.parseColor("#48BDFF");
/**
* 悬浮栏高度
*/
int mGroupHeight = 120;
/**
* 分割线颜色,默认灰色
*/
@ColorInt
int mDivideColor = Color.parseColor("#CCCCCC");
/**
* 分割线宽度
*/
int mDivideHeight = 0;
/**
* RecyclerView头部数量
* 最小为0
*/
int mHeaderCount;
Paint mDividePaint;
/**
* 缓存分组第一个item的position
*/
private SparseIntArray firstInGroupCash = new SparseIntArray(100);
protected OnGroupClickListener mOnGroupClickListener;
protected boolean mSticky = true;
public BaseDecoration() {
mDividePaint = new Paint();
mDividePaint.setColor(mDivideColor);
}
/**
* 设置点击事件
*
* @param listener
*/
protected void setOnGroupClickListener(OnGroupClickListener listener) {
this.mOnGroupClickListener = listener;
}
/**
* 获取分组名
*
* @param realPosition realPosition
* @return group
*/
abstract String getGroupName(int realPosition);
/**
* 获取真实的position
* @param position
* @return
*/
protected int getRealPosition(int position) {
return position - mHeaderCount;
}
@Override
public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
int position = parent.getChildAdapterPosition(view);
int realPosition = getRealPosition(position);
RecyclerView.LayoutManager manager = parent.getLayoutManager();
if (manager instanceof GridLayoutManager) {
//网格布局
int spanCount = ((GridLayoutManager) manager).getSpanCount();
if (!isHeader(realPosition)) {
if (isFirstLineInGroup(realPosition, spanCount)) {
//为悬浮view预留空间
outRect.top = mGroupHeight;
} else {
//为分割线预留空间
outRect.top = mDivideHeight;
}
}
} else {
//其他的默认为线性布局
//只有是同一组的第一个才显示悬浮栏
if (!isHeader(realPosition)) {
if (isFirstInGroup(realPosition)) {
//为悬浮view预留空间
outRect.top = mGroupHeight;
} else {
//为分割线预留空间
outRect.top = mDivideHeight;
}
}
}
}
/**
* 判断是不是组中的第一个位置
* 根据前一个组名,判断当前是否为新的组
* 当前为groupId为null时,则与上一个为同一组
*/
protected boolean isFirstInGroup(int realPosition) {
if (realPosition
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?