目录
- 一、ItemDecoration
- 二、实现RecyclerView吸顶效果
- 1、实现一个简单的RecyclerView
- 2、通过ItemDecoration画分割线
- 3、画出每个分组的组名
- 4、实现吸顶效果
- 完整demo

一、ItemDecoration


RecyclerView.addItemDecoration()

public abstract static class ItemDecoration
public class DividerItemDecoration extends RecyclerView.ItemDecoration
里面有3个方法:

public void onDraw(Canvas c, RecyclerView parent, State state) {
onDraw(c, parent);
}
绘制效果


public void onDrawOver(Canvas c, RecyclerView parent, State state) {
onDrawOver(c, parent);
}
绘制效果


public void getItemOffsets(Rect outRect, View view, RecyclerView parent, State state) {
getItemOffsets(outRect, ((LayoutParams)view.getLayoutParams()).getViewLayoutPosition(),
parent);
}
二、实现RecyclerView吸顶效果
1、实现一个简单的RecyclerView
下面这个RecyclerView的实现细节略。

2、通过ItemDecoration画分割线
自定义ItemDecoration。
创建 fruitDecotion 类 继承 ItemDecoration,并实现onDraw、onDrawover、getItemOffsets三个方法。
RecyclerView调用自定义的fruitDecoration
RecyclerView.addItemDecoration(new fruitDecoration(this))
在getItemOffsets画分割线,当是组名时,预留更大的空间(即分割线的height比普通分割线大)。
@Override
public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
if (parent.getAdapter() instanceof fruitAdapter){
// parent.getAdapter()获取到当前RecyclerView的Adapter
fruitAdapter adapter = (fruitAdapter) parent.getAdapter();
// 获取当前view的位置
int position = parent.getChildLayoutPosition(view);
if (adapter.isGroupHeader(position)) {
// 如果是头部,则预留更大的地方
outRect.set(0, groupHeaderHeight, 0, 0);
}else {
编程 outRect.set(0, 4, 0, 0);
}
}
实现效果

3、画出每个分组的组名
当是组名时,在较大分割线哪里画出组名。在onDraw()方法里实现
@Override
public void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
super.onDraw(c, parent, state);
if (parent.getAdapter() instanceof fruitAdapter) {
fruitAdapter adapter = (fruitAdapter) parent.getAdapter();
//当前屏幕中item的个数
int count = parent.getChildCount();
// 获取当前RecyclerView距离屏幕左边的padding
int left = parent.getPaddingLeft();
// right == RecyclerView的宽度 - RecyclerView的右padding
int right = parent.getWidth() - parent.getPaddingRight();
for (int i = 0; i < count; i++) {
//获取对应 i 的 view
View view = parent.getChildAt(i);
// 获取 i 的 view 的布局位置
int position = parent.getChildLayoutPosition(view);
// 判断是否是头部
boolean isGroupHeader = adapter.isGroupHeader(position);
// i 的 view 是头部并且 当前view的top位置距离屏幕的顶部还有距离
if(isGroupHeader && view.getTop() - groupHeaderHeight - parent.getPaddingTop() >javascript=0) {
c.drawRect(left, view.getTop() - groupHeaderHeight, right, view.getTop(), headPaint);
String groupName = adapter.getGroupName(position);
textPaint.getTextBounds(groupName, 0, groupName.length(), textRect);
c.drawText(grou开发者_Python开发pName, left + 20, view.getTop() - groupHeaderHeight / 2f + textRect.height() / 2f, textPaint);
}else if(view.getTop() - groupHeaderHeight - parent.getPaddingTop() >=0){
//分割线
c.drawRect(left, view.getTop() - 4, right, view.getTop(), headPaint);
}
}
}
}
实现效果

4android、实现吸顶效果编程
因为onDrawOver方法是在itemView画了之后才画,所以组名的吸顶是写在onDrawOver方法里。需要注意的时,当我们的第二个组名到顶部的时候,要把当前顶部的组名给替换掉。
@Override
public void onDrawOver(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
super.onDrawOver(c, parent, state);
if (parent.getAdapter() instanceof fruitAdapter) {
fruitAdapter adapter = (fruitAdapter) parent.getAdapter();
//TODO 返回可见区域内的第一个item的position
int position =((LinearLayoutManager) parent.getLayoutManager()).findFirstVisibleItemPosition();
// 获取第一个item的view
View itemView = parent.findViewHolderForAdapterPosition(position).itemView;
int left = parent.getPaddingLeft();
int right = parent.getWidth() - parent.getPaddingRight();
int top = parent.getPaddingTop();
//TODO 当第二个是头部时,
boolean isGroupHeader = adapter.isGroupHeader(position + 1);
if (isGroupHeader) {
int bottom = Math.minjavascript(groupHeaderHeight, itemView.getBottom() - parent.getPaddingTop());
c.drawRect(left, top, right, top + bottom, headPaint);
String groupName = adapter.getGroupName(position);
textPaint.getTextBounds(groupName, 0, groupName.length(), textRect);
c.drawText(groupName, left + 20, top + bottom - groupHeaderHeight / 2f
+ textRect.height() / 2f, textPaint);
}else { // 如果不是头部, 即普通的itemView,则当前的头部一直固定在顶部
c.drawRect(left, top, right, top + groupHeaderHeight, headPaint);;
String groupName = adapter.getGroupName(position);
textPaint.getTextBounds(groupName, 0, groupName.length(), textRect);
c.drawText(groupName, left + 20, top + groupHeaderHeight / 2f
+ textRect.height() / 2f, textPaint);
}
}
}
实现效果

完整demo
链接: https://pan.baidu.com/s/11I8dtWts3BZjYMgNvzanTw?pwd=bvx9
到此这篇关于android RecyclerView实现吸顶动态效果流程分析的文章就介绍到这了,更多相关Android RecyclerView内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!
加载中,请稍侯......
精彩评论