Model
public class Model {
private String mTitle;
public Model(String title) {
mTitle = title;
}
public String getTitle() {
return mTitle;
}
}
RecyclerView使用
mModelList.add(new Model("标题一"));
mModelList.add(new Model("标题二"));
mModelList.add(new Model("标题三"));
//添加吸顶功能
//mContentRootLayout是RecycleView背景色使用的布局layout
mFunctionRecyclerView.addItemDecoration(new StickyItemDecoration(this, mContentRootLayout.getBackground(),new ISticky() {
@Override
public boolean isFirstPosition(int pos) {
return pos==0||
!mModelList.get(pos).getTitle().equals(mModelList.get(pos-1).getTitle());
}
@Override
public String getGroupTitle(int pos) {
return mModelList.get(pos).getTitle();
}
@Override
public int findFirstVisibleItemPosition() {
return mFunctionLinearLayoutManager.findFirstVisibleItemPosition();
}
}));
mFunctionAdapter = new FunctionAdapter(this, mModelList);
mFunctionLinearLayoutManager = new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false);
mFunctionRecyclerView.setLayoutManager(mFunctionLinearLayoutManager);
mFunctionRecyclerView.setAdapter(mFunctionAdapter);
接口
public interface ISticky {
//判断是否为同类别的第一个位置
boolean isFirstPosition(int pos);
//获取标题
String getGroupTitle(int pos);
//获取第一个位置
int findFirstVisibleItemPosition();
}
核心代码StickyItemDecoration
public class StickyItemDecoration extends RecyclerView.ItemDecoration {
private ISticky mISticky;
//矩形高度
private int mRectHeight;
//文字TextSize
private int mTextPaintSize;
private Paint mTxtPaint;
private Paint mRectPaint;
private Paint mTransparentRectPaint;
//分割线画笔
private Paint mDividerPaint;
private Bitmap mBitmap;
private Rect mRect;
private RectF mRectF;
public StickyItemDecoration(Context context, Drawable drawable, ISticky iSticky) {
mISticky=iSticky;
mRectHeight= (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,76,
context.getResources().getDisplayMetrics());
mTextPaintSize=(int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,32,
context.getResources().getDisplayMetrics());
mTxtPaint=new Paint(Paint.ANTI_ALIAS_FLAG);
mTxtPaint.setColor(Color.WHITE);
mTxtPaint.setTextSize(mTextPaintSize);
mRectPaint=new Paint(Paint.ANTI_ALIAS_FLAG);
mRectPaint.setStyle(Paint.Style.FILL);
//mRectPaint.setColor(Color.parseColor("#1D2024"));
//mRectPaint.setColor(Color.TRANSPARENT);
mTransparentRectPaint =new Paint(Paint.ANTI_ALIAS_FLAG);
mTransparentRectPaint.setStyle(Paint.Style.FILL);
mTransparentRectPaint.setColor(Color.TRANSPARENT);
mDividerPaint=new Paint(Paint.ANTI_ALIAS_FLAG);
mDividerPaint.setStyle(Paint.Style.FILL);
//mDividerPaint.setColor(Color.WHITE);
mDividerPaint.setColor(Color.TRANSPARENT);
//Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
Bitmap bitmap = drawableToBitmap(drawable);
//todo 项目线要对此做适配,此处写的为吸顶栏的起点坐标以及长宽,如果是多屏幕适配此处也要做对应规则计算
mBitmap = Bitmap.createBitmap(bitmap, 328, 96, 724, 76, null, false);
mRect = new Rect(0,0,724,76);
mRectF = new RectF(0,0,724,76);
}
private Bitmap drawableToBitmap(Drawable drawable) {
//1920,720是图片的大小
int width = DensityUtils.dip2px(ContextUtil.getContext(),1920);
int height = DensityUtils.dip2px(ContextUtil.getContext(),720);
Bitmap bitmap = Bitmap.createBitmap( width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, width, height);
drawable.draw(canvas);
return bitmap;
}
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
super.onDraw(c, parent, state);
int childCount=parent.getChildCount();
for (int i = 0; i < childCount; i++) {
View view=parent.getChildAt(i);
int left=parent.getPaddingLeft();
int right=parent.getWidth()-parent.getPaddingRight();
int top=view.getTop()-1;
int bottom=view.getTop();
//Item分割线
c.drawRect(left,top,right,bottom,mDividerPaint);
//c.drawBitmap(mBitmap,0,0,mRectPaint);
//核心代码一,此处可能不需要
c.drawBitmap(mBitmap, mRect, mRectF,mRectPaint);
}
}
@Override
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
super.onDrawOver(c, parent, state);
int childCount=parent.getChildCount();
int itemCount=state.getItemCount();
int left=parent.getPaddingLeft();
int right=parent.getWidth()-parent.getPaddingRight();
String preGroupTitle;
String groupTitle="";
for (int i = 0; i < childCount; i++) {
View child=parent.getChildAt(i);
int pos=parent.getChildLayoutPosition(child);
preGroupTitle=groupTitle;
groupTitle=mISticky.getGroupTitle(pos);
//如果当前分组名和之前分组名一样,忽略此次循环
if (groupTitle.equals(preGroupTitle)) {
continue;
}
//文字的基线,保证显示完全
int textBaseLine=Math.max(mRectHeight,child.getTop());
//分组标题
String title=mISticky.getGroupTitle(pos);
int viewBottom=child.getBottom();
//加入限定 防止数组越界
if (pos + 1 < itemCount) {
String nextGroupTitle=mISticky.getGroupTitle(pos+1);
//当分组不一样 并且改组要向上移动时候
if (!nextGroupTitle.equals(groupTitle) && viewBottom < textBaseLine) {
//将上一个往上移动
textBaseLine = viewBottom;
}
}
//绘制边框
//核心代码二
if (pos == mISticky.findFirstVisibleItemPosition()){
//c.drawBitmap(mBitmap,0,0,mRectPaint);
c.drawBitmap(mBitmap, mRect, mRectF,mRectPaint);
}else {
c.drawRect(left, textBaseLine - mRectHeight, right, textBaseLine, mTransparentRectPaint);
}
//绘制文字并且实现文字居中
int value= (int) Math.abs(mTxtPaint.getFontMetrics().descent
+mTxtPaint.getFontMetrics().ascent);
c.drawText(title, left,
textBaseLine-(mRectHeight-value)/2,
mTxtPaint);
}
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
int pos=parent.getChildLayoutPosition(view);
if (mISticky.isFirstPosition(pos)) {
outRect.top=mRectHeight;
outRect.bottom=1;
}else {
outRect.bottom=1;
}
}
}
实现的思想是给显示在正在吸顶的添加一个背景图,没有吸顶的设置为透明