RecycleView设置顶部分割线(记录一个坑)
程序员文章站
2022-08-08 08:54:55
大家都知道,想给RecycleView设置分割线可以重写RecyclerView.ItemDecoration 项目过程中,遇到一个需求:RecycleView顶部有一条灰色的间隔,我想到了给RecycleView设置分割线的方法,当然只给第一个Item设置,而且在上方。 在onDrawOver方法 ......
大家都知道,想给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); } @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>