public class SectionDecoration extends RecyclerView.ItemDecoration { @Override public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) { super.onDraw(c, parent, state); } @Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { super.getItemOffsets(outRect, view, parent, state); } }
一共就提供2个方法
方法一
自定义itemDecoration public class MyItemDecoration extends RecyclerView.ItemDecoration { @Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { System.out.println("left = " + outRect.left); System.out.println("top = " + outRect.top); System.out.println("right = " + outRect.right); System.out.println("bottom = " + outRect.bottom); // super.getItemOffsets(outRect, view, parent, state); } @Override public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) { super.onDrawOver(c, parent, state); } } getItemOffsets 参数一 outRect的默认值是 0 : 01-23 17:33:31.727 24556-24556/com.adnonstop.brvah I/System.out: left = 0 01-23 17:33:31.727 24556-24556/com.adnonstop.brvah I/System.out: top = 0 01-23 17:33:31.727 24556-24556/com.adnonstop.brvah I/System.out: right = 0 01-23 17:33:31.727 24556-24556/com.adnonstop.brvah I/System.out: bottom = 0 修改outRect @Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { outRect.set(60, 60, 60, 60); System.out.println("left = " + outRect.left); System.out.println("top = " + outRect.top); System.out.println("right = " + outRect.right); System.out.println("bottom = " + outRect.bottom); // super.getItemOffsets(outRect, view, parent, state); 一定要注销掉;因为 父类执行的是 outRect.set(0,0,0,0); } outRect的值 01-23 17:37:46.037 31451-31451/com.adnonstop.brvah I/System.out: left = 60 01-23 17:37:46.037 31451-31451/com.adnonstop.brvah I/System.out: top = 60 01-23 17:37:46.037 31451-31451/com.adnonstop.brvah I/System.out: right = 60 01-23 17:37:46.037 31451-31451/com.adnonstop.brvah I/System.out: bottom = 60
方法一作用,类似于给每一个Item布局设置margin或padding
完整定义
linearlayoutManager的分割线 public class MyItemDecoration extends RecyclerView.ItemDecoration { private final Drawable drawable; public MyItemDecoration(Context context) { drawable = ContextCompat.getDrawable(context, R.drawable.item_divider); } /** * 如果 只需要设置linearlayoutmanager 的分割线,那么只需要设置outRect.top 值即可。 * @param outRect * @param view * @param parent * @param state */ @Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { /** * 跳过索引为0的item */ if (parent.getChildLayoutPosition(view) < 1) { return; } /** * 设置item的相对偏移量 */ outRect.top = drawable.getIntrinsicHeight(); } /** * 切记: 从 索引为 1 的 item 开始画 * * @param c * @param parent * @param state */ @Override public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) { int childCount = parent.getChildCount(); int rightV = parent.getWidth(); for (int i = 0; i < childCount; i++) { View child = parent.getChildAt(i); RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); int leftV = parent.getPaddingLeft() + child.getPaddingLeft(); //从索引的为1 的item开始绘制的。 int bottomV = child.getTop() - params.topMargin; int topV = bottomV - drawable.getIntrinsicHeight(); drawable.setBounds(leftV, topV, rightV, bottomV); drawable.draw(c); } } } Drawable使用shape绘制: item_divider.xml <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <size android:height="10dp" /> <solid android:color="@color/colorAccent" /> </shape>
当条目总数为0时,不会调用itemDecotation的方法的。
当itemCount = 3,看itemDecoration方法执行的顺序
02-10 12:28:14.566 6626-6626/com.qingmu.footerrecyclerview I/SectionDecorationchild: getItemOffsets: = 1 02-10 12:28:14.566 6626-6626/com.qingmu.footerrecyclerview I/SectionDecorationchild: getItemOffsets: = 2 02-10 12:28:14.576 6626-6626/com.qingmu.footerrecyclerview I/SectionDecorationchild: getItemOffsets: = 3 02-10 12:28:14.576 6626-6626/com.qingmu.footerrecyclerview I/SectionDecorationchild: onDraw: = 3 02-10 12:28:15.026 6626-6626/com.qingmu.footerrecyclerview I/SectionDecorationchild: onDraw: = 3
显然是根据itemCount执行itemCount次getItemOffSets,然后再执行itemCount-1次onDraw。
//一般情况下params.TopMargin = 0 ,所以bottomV = child.getTop(); int bottomV = child.getTop() - params.topMargin;//这个params.TopMargin并非getItemOffSets的outRect.top = topGap;
/** * y值越小,越靠上 * bottomV 注定大于 TopV * * @param c * @param parent * @param state */ @Override public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {