今天介绍一种比较简单的RecyclerView头部悬浮吸顶效果的实现方式,通过自定义RecyclerView的ItemDecoration分割线即可实现,不需要其他辅助类。实现效果如下:
RecyclerView提供了静态抽象类ItemDecoration来实现自定义分割线效果,主要涉及三个方法:onDraw( ),
onDrawOver( ),getItemOffsets( )。
public abstract static class ItemDecoration { @Deprecated public void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent) { } public void onDrawOver(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull State state) { onDrawOver(c, parent); } @Deprecated public void onDrawOver(@NonNull Canvas c, @NonNull RecyclerView parent) { } @Deprecated public void getItemOffsets(@NonNull Rect outRect, int itemPosition, @NonNull RecyclerView parent) { outRect.set(0, 0, 0, 0); } public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull State state) { getItemOffsets(outRect, ((LayoutParams) view.getLayoutParams()).getViewLayoutPosition(), parent); } }
我们先看getItemOffsets( )方法,getItemOffsets 用来设置分割线的间距大小,通过设置outRect矩形的宽高实现分割线效果。
首先通过RecyclerView的getChildAdapterPosition 得到item在adapter中的位置position,然后获取Item的适配器,通过适配器中定义的getViewIsFirst方法判断当前位置是否是分组。
如果当前位置是分组则,设置分割线为Item的高度,否则设置为普通分割线高度。得到效果如下:
getItemOffsets( )方法中,我们为分割线和分组的位置都预留了空间,接下来我们需要绘制分组文字和填充分割线颜色。
通过适配器获取当前位置的组名,然后调用Canvas的drawText方法将文字绘制到分组中。
效果如下:
onDrawOver()方法,顾名思义是在Item绘制完成后在最上层绘制调用的。我们要实现头部悬浮吸顶效果,必须在RecyclerView最上面绘制一个红色背景悬浮的分组名,当下面的分组滑到最上面时,将红色背景悬浮的分组挤出屏幕替换。
首先我们需要在最上面绘制一个红色背景悬浮分组。
这个悬浮分组的位置固定在RecyclerView的头部。绘制完头部后,接下来需要实现滑动效果,当第二个分组名“北京第1”滑动到屏幕中第二个Item的位置时,红色背景悬浮的分组才开始向上滑出屏幕。直到第二个分组名占据屏幕最顶部位置。
首先我们需要得到屏幕顶部显示的View,当“北京第1”向上滑动时,顶部的View高度不断变小,直到消失。
最终顶部View被“北京第1”替代。显示效果如下: