大家都知道,想给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>
原文地址:https://www.cnblogs.com/tangZH/p/9489486.html
时间: 2024-10-25 08:00:01