上面的代码中,我们给ItemDecoration 预留了一个划线的空间
运行如下:
- 在Adapter 中判断当前组的第一个item 是不是头部
// 是否是组的第一个Item
public boolean isFirstItemOfGroup(int position) {
if (position == 0) {
return true;
} else {
// 拿到当前位置的和前一个位置的 组名
String currentItemGroupName = getGroupName(position);
String preItemGroupName = getGroupName(position - 1);
// 如果相等,则表示position 的 item 不是第一个,否则是
if (currentItemGroupName.equals(preItemGroupName)) {
return false;
} else {
return true;
}
}
}
- 在 获取到头部 item 之后,预留一个绘制空间
// 判断 Item 是头部
boolean isGroupHeader = starAdapter.isFirstItemOfGroup(position);
if (isGroupHeader){
// headerHeight 是头部 Item 的高度
outRect.set(0, headerHeight, 0, 0);
}else {
// decorationTop 分割线的高度
outRect.set(0, decorationTop, 0, 0);
}
在 getItemOffsets()
中添加上面代码后,预留的 item 的头部空间就出来了,运行如下
// 绘制自己
@Override
public void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
super.onDraw(c, parent, state);
if (parent.getAdapter() instanceof StarAdapter){
StarAdapter starAdapter = (StarAdapter) parent.getAdapter();
// 当前屏幕上展示的
int count = parent.getChildCount();
// 实现 itemView 的宽度和分割线的宽度一样
int left = parent.getPaddingLeft();
int right = parent.getWidth() - parent.getPaddingLeft();
for (int i = 0; i < count; i++) {
View view = parent.getChildAt(i);
// 当前item 的位置
int position = parent.getChildLayoutPosition(view);
// 判断是否是头部
boolean isGroupHeader = starAdapter.isFirstItemOfGroup(position);
if (isGroupHeader){
c.drawRect(left, view.getTop() - headerHeight, right, view.getTop(), headPaint);
// 获取当前组名
String groupName = starAdapter.getGroupName(position);
c.drawText(groupName,left + groupNameLeftPadding,
view.getTop() - headerHeight / 2 + textRect.height() / 2,
drawTextPaint);
}else {
c.drawRect(left, view.getTop() - valueHeight, right, view.getTop(), headPaint);
}
}
}
}
代码运行结果如下:
// 绘制吸顶效果
@Override
public void onDrawOver(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
super.onDrawOver(c, parent, state);
if (parent.getAdapter() instanceof StarAdapter){
StarAdapter starAdapter = (StarAdapter) parent.getAdapter();
int left = parent.getPaddingLeft();
int right = parent.getRight();
int top = parent.getTop();
// 当前显示在界面的第一个 item
int position = ((LinearLayoutManager)parent.getLayoutManager()).findFirstVisibleItemPosition();
View itemView = parent.findViewHolderForAdapterPosition(position).itemView;
// 获取当前的上一个 头部 item
boolean isFirstItemOfGroup = starAdapter.isFirstItemOfGroup(position +1 );
if(isFirstItemOfGroup){
int bottom = Math.min(top + headerHeight, itemView.getBottom());
c.drawRect(left, top, right, bottom, headPaint);
String groupName = starAdapter.getGroupName(position);
drawTextPaint.getTextBounds(groupName, 0, groupName.length(), textRect);
c.clipRect(left, top, right, bottom);
c.drawText(groupName, left + 20,
bottom - headerHeight / 2 + textRect.height() / 2, drawTextPaint);
}else {
// 固定的头部信息
c.drawRect(left, top, right, top + headerHeight, headPaint);
String groupName = starAdapter.getGroupName(position);
drawTextPaint.getTextBounds(groupName, 0, groupName.length(), textRect);
// 绘制文字
c.drawText(groupName, left + 20, top + headerHeight / 2 + textRect.height() /2, drawTextPaint);
}
}
}
运行结果如下:
public class StarDecoration extends RecyclerView.ItemDecoration {
// 分组栏的高度
private int headerHeight;
private int valueHeight = 50;
private Paint headPaint;
private Paint drawTextPaint;
private Rect textRect;
private int decorationTop = 4;
// 组名的 padding
private int groupNameLeftPadding = 20;
public StarDecoration(Context context){
// 顶部吸顶栏的高度
headerHeight = dp2px(context, valueHeight);
// 每一组的头部的Paint
headPaint = new Paint();
headPaint.setColor(Color.RED);
drawTextPaint = new Paint();
drawTextPaint.setColor(Color.YELLOW);
drawTextPaint.setTextSize(50);
textRect = new Rect();
}
// 绘制自己
@Override
public void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
super.onDraw(c, parent, state);
if (parent.getAdapter() instanceof StarAdapter){
StarAdapter starAdapter = (StarAdapter) parent.getAdapter();
// 当前屏幕上展示的
int count = parent.getChildCount();
// 实现 itemView 的宽度和分割线的宽度一样
int left = parent.getPaddingLeft();
int right = parent.getWidth() - parent.getPaddingLeft();
for (int i = 0; i < count; i++) {
View view = parent.getChildAt(i);
// 当前item 的位置
int position = parent.getChildLayoutPosition(view);
// 判断是否是头部
boolean isGroupHeader = starAdapter.isFirstItemOfGroup(position);
if (isGroupHeader){
c.drawRect(left, view.getTop() - headerHeight, right, view.getTop(), headPaint);
// 获取当前组名
String groupName = starAdapter.getGroupName(position);
c.drawText(groupName,left + groupNameLeftPadding,
view.getTop() - headerHeight / 2 + textRect.height() / 2,
drawTextPaint);
}else {
c.drawRect(left, view.getTop() - decorationTop, right, view.getTop(), headPaint);
}
}
}
}
// 绘制吸顶效果
@Override
public void onDrawOver(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
super.onDrawOver(c, parent, state);
if (parent.getAdapter() instanceof StarAdapter){
StarAdapter starAdapter = (StarAdapter) parent.getAdapter();
int left = parent.getPaddingLeft();
int right = parent.getRight();
int top = parent.getTop();
// 当前显示在界面的第一个 item
int position = ((LinearLayoutManager)parent.getLayoutManager()).findFirstVisibleItemPosition();
View itemView = parent.findViewHolderForAdapterPosition(position).itemView;
// 获取当前的上一个 头部 item
boolean isFirstItemOfGroup = starAdapter.isFirstItemOfGroup(position +1 );
if(isFirstItemOfGroup){
int bottom = Math.min(top + headerHeight, itemView.getBottom());
c.drawRect(left, top, right, bottom, headPaint);
String groupName = starAdapter.getGroupName(position);
drawTextPaint.getTextBounds(groupName, 0, groupName.length(), textRect);
c.clipRect(left, top, right, bottom);
c.drawText(groupName, left + 20,
bottom - headerHeight / 2 + textRect.height() / 2, drawTextPaint);
}else {
// 固定的头部信息
c.drawRect(left, top, right, top + headerHeight, headPaint);
String groupName = starAdapter.getGroupName(position);
drawTextPaint.getTextBounds(groupName, 0, groupName.length(), textRect);
// 绘制文字
c.drawText(groupName, left + 20, top + headerHeight / 2 + textRect.height() /2, drawTextPaint);
}
}
}
@Override
public void getItemOffsets(@NonNull Rect outRect, @NonNull View view,
@NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
// 绑定自己的 Adapter
if (parent.getAdapter() instanceof StarAdapter){
StarAdapter starAdapter = (StarAdapter) parent.getAdapter();
// 当前item 的位置
int position = parent.getChildLayoutPosition(view);
// 判断 Item 是头部
boolean isGroupHeader = starAdapter.isFirstItemOfGroup(position);
if (isGroupHeader){
// headerHeight 是头部 Item 的高度
outRect.set(0, headerHeight, 0, 0);
}else {
// decorationTop 分割线的高度
outRect.set(0, decorationTop, 0, 0);
}
}
}
/**
-
分辩率
-
@param context
-
@param dpValue
-
@return
*/
private int dp2px(Context context, float dpValue){
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpValue,
context.getResources().getDisplayMetrics());
}
}
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
学习分享
在当下这个信息共享的时代,很多资源都可以在网络上找到,只取决于你愿不愿意找或是找的方法对不对了
很多朋友不是没有资料,大多都是有几十上百个G,但是杂乱无章,不知道怎么看从哪看起,甚至是看后就忘
如果大家觉得自己在网上找的资料非常杂乱、不成体系的话,我也分享一套给大家,比较系统,我平常自己也会经常研读。
2021最新上万页的大厂面试真题
七大模块学习资料:如NDK模块开发、Android框架体系架构…
只有系统,有方向的学习,才能在段时间内迅速提高自己的技术。
这份体系学习笔记,适应人群:
**第一,**学习知识比较碎片化,没有合理的学习路线与进阶方向。
**第二,**开发几年,不知道如何进阶更进一步,比较迷茫。
**第三,**到了合适的年纪,后续不知道该如何发展,转型管理,还是加强技术研究。
由于文章内容比较多,篇幅不允许,部分未展示内容以截图方式展示 。
一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!
AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算
Android框架体系架构…**
[外链图片转存中…(img-SnbFiVXb-1712102032098)]
只有系统,有方向的学习,才能在段时间内迅速提高自己的技术。
这份体系学习笔记,适应人群:
**第一,**学习知识比较碎片化,没有合理的学习路线与进阶方向。
**第二,**开发几年,不知道如何进阶更进一步,比较迷茫。
**第三,**到了合适的年纪,后续不知道该如何发展,转型管理,还是加强技术研究。
由于文章内容比较多,篇幅不允许,部分未展示内容以截图方式展示 。
一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!
AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算