大家都知道,想给RecycleView设置分割线可以重写RecyclerView.ItemDecoration

项目过程中,遇到一个需求:RecycleView顶部有一条灰色的间隔,我想到了给RecycleView设置分割线的方法,当然只给第一个Item设置,而且在上方。

public class MyDividerItemDecoration extends RecyclerView.ItemDecoration {

    private Drawable mDivider;

    /**
* Custom divider will be used
*/
public MyDividerItemDecoration(Context context, int resId) {
mDivider = ContextCompat.getDrawable(context, resId);
}
    public DividerItemDecoration(Drawable drawable) {
mDivider = drawable;
}
  @Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, 
RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
//因为绘制了顶部分割线,因此需要将第一行的item下移相应的距离
//这里要注意,判断该RecycleView是什么布局,如果是竖直方向上的线性布局(水平方向上的这里没有考虑)
//,那么需要让第一个Item下移,移动的距离是分割线的高度,因为分割线会占据Item的空间
//如果是网格布局,那么需要把第一行的所有Item都下移相应的高度
if (layoutManager instanceof LinearLayoutManager) {
if (parent.getChildAdapterPosition(view) == 0) {
outRect.set(0, mDivider.getIntrinsicHeight(), 0, 0);
}
}
if (layoutManager instanceof GridLayoutManager) {
if (parent.getChildAdapterPosition(view) >= 0 &&
parent.getChildAdapterPosition(view) < getSpanCount(parent)) {
outRect.set(0, mDivider.getIntrinsicHeight(), 0, 0);
}
}
} @Override
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) { //绘制分割线
int left = 0;
int right = parent.getWidth();
View child = parent.getChildAt(0); RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); //不可以直接设置top = 0;因为这样的话分隔线就不会跟着移动,因为top = 0,是绝对位置,
//所以应该设置为子view的相对位置
//这样才可以跟着滑动。
//child的顶部坐标,减去设置的margin_top的值,再减去child为了给分割线腾出空间所下滑的高度,
//这样分割线才会在顶部
int top = child.getTop() - params.topMargin - mDivider.getIntrinsicHeight();
int bottom;
bottom = top + mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
} private int getSpanCount(RecyclerView parent) {
// 列数
int spanCount = -1;
RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
if (layoutManager instanceof GridLayoutManager) {
spanCount = ((GridLayoutManager) layoutManager).getSpanCount();
} else if (layoutManager instanceof StaggeredGridLayoutManager) {
spanCount = ((StaggeredGridLayoutManager) layoutManager)
.getSpanCount();
} else if (layoutManager instanceof LinearLayoutManager) {
spanCount = layoutManager.getItemCount();
}
return spanCount;
}

在onDrawOver方法中可以绘制分割线。

这里有一个需要注意的坑,调试了很久,最终才发现,难受。

在onDrawOver里面,一开始我设置top = 0;因为绘制在顶部嘛。结果出现了一个现象,顶部分割线一直停留在顶部,不会跟着移动。最后改为int top = child.getTop() - params.topMargin - mDivider.getIntrinsicHeight();才成功了。为什么呢?

因为直接写top = 0;这是绝对位置了,要让分割线也跟着滑动,需要用的是相对位置,相对于item的位置,这样才能够跟着item滑动

调用

recyclerView.addItemDecoration(new MyDividerItemDecoration(this, R.drawable.item_decoration));

item_decoration代码如下:

<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<size android:height="10dp" />
<solid android:color="@color/comic_gray_bg" />
</shape>

 

或者我们可以直接代码中创建Drawable,然后传进去:

//添加白色分割线在顶部
GradientDrawable drawable = new GradientDrawable();
drawable.setColor(ContextCompat.getColor(this, R.color.white));
drawable.setShape(GradientDrawable.RECTANGLE);
drawable.setSize(0, 3);
recyclerView.addItemDecoration(new DividerItemDecoration(drawable));

尊重劳动成果,转载请标明出处:https://www.cnblogs.com/tangZH/p/9489486.html 

RecycleView设置顶部分割线(记录一个坑)的更多相关文章

  1. 关于pyinstaller打包程序时设置icon时的一个坑

    关于pyinstaller打包程序时设置icon时的一个坑     之前在用pyinstaller打包程序的时候遇到了关于设置图标的一点小问题,无论在后面加--icon 或是-i都出现报错.查了下st ...

  2. allegro设置内存分配器的一个坑

    看过<游戏引擎架构>后我开始对内存的分配问题关注,一直想用内存分配器来管理游戏的内存.前两天发现了有许多第三方内存分配器可以用.最后挑中了nedmalloc,这个库也是ogre所使用的,测 ...

  3. 记录我开发工作中遇到HTTP跨域和OPTION请求的一个坑

    我通过这篇文章把今天工作中遇到的HTTP跨域和OPTION请求的一个坑记录下来. 场景是我需要在部署在域名a的Web应用里用JavaScript去消费一个部署在域名b的服务器上的服务.域名b上的服务也 ...

  4. 再次记录 Visual Studio 2015 CTP 5 的一个坑

    接上一篇:升级 Visual Studio 2015 CTP 5 的坑.坑.坑 升级到 VS2015 CTP 之后,今天要改项目中的一个东西,然后就不得不把 C# 6.0 改变的语法代码中改了下(之前 ...

  5. 记录js new Date日期处理的一个坑

    记录js日期处理的一个坑   当前时区为北美东部时区时, new Date('2019-4-1') new Date('2019-04-01') 结果是相关一个月的. 如下图   new Date(' ...

  6. Android中隐藏顶部状态栏的那些坑——Android开发之路3

    Android中隐藏顶部状态栏的那些坑 先看看常规的隐藏状态栏的方法: 方法一: @Override protected void onCreate(Bundle savedInstanceState ...

  7. andriod8.1.0源码编译中的一个坑-package com.sun.javadoc does not exist

    这里记录编译过程中的一个坑!!! 编译过程中出现了下面的报错 external/doclava/src/com/google/doclava/ClassInfo.java:20: error: pac ...

  8. 【转载】linux命令行计算器bc的一个“坑”

    [转载自]http://blog.chinaunix.net/uid-174325-id-3518953.html 结论:ibase,obase可以使用在不同的计算公式里,但是尽量把obase放iba ...

  9. 使用ffmpeg视频编码过程中踩的一个坑

           今天说说使用ffmpeg在写视频编码程序中踩的一个坑,这个坑让我花了好多时间,回头想想,非常多时候一旦思维定势真的挺难突破的.以下是不对的编码结果:                   ...

随机推荐

  1. Tomcat 集群中 实现session 共享的三种方法

    前两种均需要使用 memcached 或 redis 存储 session ,最后一种使用 terracotta 服务器共享. 建议使用 redis ,不仅仅因为它可以将缓存的内容持久化,还因为它支持 ...

  2. [Swift]LeetCode749. 隔离病毒 | Contain Virus

    A virus is spreading rapidly, and your task is to quarantine the infected area by installing walls. ...

  3. [Swift]LeetCode887. 鸡蛋掉落 | Super Egg Drop

    You are given K eggs, and you have access to a building with N floors from 1 to N. Each egg is ident ...

  4. [Swift]LeetCode1015. 可被 K 整除的最小整数 | Smallest Integer Divisible by K

    Given a positive integer K, you need find the smallest positive integer N such that N is divisible b ...

  5. BBS论坛(二十一)

    21.1.编辑轮播图功能完成 (1)cms_banners.html 把属性绑定到<tr>上面,方便找到各属性的值 <tbody> {% for banner in banne ...

  6. node开发备注

    设置环境变量 // 命令行启动: "scripts": { "start": "export NODE_ENV=dev && node ...

  7. Python高级特性(一)

    一.切片 L = ['Michael', 'Sarah', 'Tracy', 'Bob', 'Jack']取出前三个元素 , 笨方法就是通过下标一个一个获取 [L[0], L[1], L[2]]Pyt ...

  8. Chapter 5 Blood Type——12

    I blinked, my mind going blank. Holy crow, how did he do that? 我眨着眼睛,心里一片空白.天哪,他是怎么做到的? "Er, wh ...

  9. java nginx等代理或网关转发请求后获取客户端的ip地址,原理

    在没有网关或者反向代理软件情况下,java里获取客户端ip地址的方法是request.getRemoteAddr() 先解释下http协议和TCP协议: 网页默认是进行http连接了,http协议即超 ...

  10. adb server is out of date. killing... ADB server didn't ACK解决方法

    在使用ADT Bundle进Android开发时,有时经常会碰到如下错误提示: adb server is out of date. killing... ADB server didn't ACK ...