总结下RecyclerView 悬浮/粘性头部实现的3种方式:
1,xml布局中设定悬浮/粘性头部view,在RecyclerView滑动过程中动态修改其位置;
参考:https://www.diycode.cc/topics/408
2,ItemDecoration 实现(高耦合)
参考:https://blog.csdn.net/qian520ao/article/details/76167193
https://www.jianshu.com/p/b335b620af39
但是以上两种方式onDrawOver()方法实现逻辑对初次查看该段代码要花时间理解。下面代码逻辑(原理一样,同样参考大神代码)相对清晰,易理解
public class StickyDecoration extends RecyclerView.ItemDecoration { ...... @Override public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) { super.onDrawOver(c, parent, state); int childCount = parent.getChildCount(); for (int i = 0; i < childCount; i++) { View view = parent.getChildAt(i); int index = parent.getChildAdapterPosition(view); if (mCallback != null) { GroupInfo groupinfo = mCallback.getGroupInfo(index); int left = parent.getPaddingLeft(); int right = parent.getWidth() - parent.getPaddingRight(); //屏幕上第一个可见的 ItemView 时,i == 0; if (i != 0) { //只有组内的第一个ItemView之上才绘制 if (groupinfo.isFirstViewInGroup()) { int top = view.getTop() - mHeaderHeight; int bottom = view.getTop(); drawHeaderRect(c, groupinfo, left, top, right, bottom); } } else { //当 ItemView 是屏幕上第一个可见的View 时,不管它是不是组内第一个View //它都需要绘制它对应的 StickyHeader。 // 还要判断当前的 ItemView 是不是它组内的最后一个 View int top = parent.getPaddingTop(); if (groupinfo.isLastViewInGroup()) { int suggestTop = view.getBottom() - mHeaderHeight; // 当 ItemView 与 Header 底部平齐的时候,判断 Header 的顶部是否小于 // parent 顶部内容开始的位置,如果小于则对 Header.top 进行位置更新, //否则将继续保持吸附在 parent 的顶部 if (suggestTop < top) { top = suggestTop; } } int bottom = top + mHeaderHeight; drawHeaderRect(c, groupinfo, left, top, right, bottom); } } } } private void drawHeaderRect(Canvas c, GroupInfo groupinfo, int left, int top, int right, int bottom) { //绘制Header c.drawRect(left, top, right, bottom, mPaint); float titleX = left + mTextOffsetX; float titleY = bottom - mFontMetrics.descent; //绘制Title c.drawText(groupinfo.getTitle(), titleX, titleY, mTextPaint); } }3,不同item type结合ItemDecoration 实现(业务解耦,插即用的)
参考:https://juejin.im/post/5a70139ff265da3e274574cb