一、先看效果:
二、简述实现方法
1、 给RecyclerView添加ItemDecoration(recyclerView.addItemDecoration(new DividerItemDecoration(this));)
2、实现ItemDecoration (在getItemOffsets 指定要绘制分割线的偏移量,onDraw 绘制自己的间隔线)
3、如果用系统的什么东不用做,如果用自己的替换主题属性listDivider(<item name="android:listDivider">@drawable/shape_item_divider</item>)
三、实现代码
DividerItemDecoration.java
public class DividerItemDecoration extends RecyclerView.ItemDecoration {
private int mOrientation = -1;
private Drawable mDivider;
//给分割线加距离左右的边距
private int paddingLeft = 0, paddingRight = 0;
private int[] attrs = new int[]{
android.R.attr.listDivider
};
public DividerItemDecoration(Context context, int orientation) {
TypedArray typedArray = context.obtainStyledAttributes(attrs);
mDivider = typedArray.getDrawable(0);
typedArray.recycle();
setOrientation(orientation);
}
public DividerItemDecoration(Context context) {
TypedArray typedArray = context.obtainStyledAttributes(attrs);
mDivider = typedArray.getDrawable(0);
typedArray.recycle();
}
public void setOrientation(int mOrientation) {
if (mOrientation != LinearLayoutManager.HORIZONTAL && mOrientation != LinearLayoutManager.VERTICAL) {
throw new IllegalArgumentException("嗨,给个布局吧");
}
this.mOrientation = mOrientation;
}
public void setPaddingLR(int left, int right) {
this.paddingLeft = left;
this.paddingRight = right;
}
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
super.onDraw(c, parent, state);
// 2、调用这个绘制方法 RecyclerView会毁掉该绘制方法,需要你自己去绘制条目的间隔线
if (mOrientation == LinearLayoutManager.VERTICAL) {
//垂直
drawVertical(c, parent);
} else if (mOrientation == LinearLayoutManager.HORIZONTAL) {
// 水平
drawHorizontal(c, parent);
} else {
drawHorizontal2(c, parent);
drawVertical2(c, parent);
}
}
private void drawHorizontal2(Canvas canvas, RecyclerView parent) {
//绘制水平间隔线
int childcount = parent.getChildCount();
for (int i = 0; i < childcount; i++) {
View child = parent.getChildAt(i);
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
int left = child.getLeft() - params.leftMargin;
int right = child.getRight() + params.rightMargin;
int top = child.getBottom() + params.bottomMargin;
int bottom = top + mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(canvas);
}
}
private void drawVertical2(Canvas canvas, RecyclerView parent) {
//绘制垂直间隔线
int childcount = parent.getChildCount();
for (int i = 0; i < childcount; i++) {
View child = parent.getChildAt(i);
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
int left = child.getRight() + params.rightMargin;
int right = left + mDivider.getIntrinsicWidth();
int top = child.getTop() - params.topMargin;
int bottom = child.getBottom() + params.bottomMargin;
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(canvas);
}
}
private void drawHorizontal(Canvas canvas, RecyclerView parent) {
int top = parent.getPaddingTop();
int bottom = parent.getHeight() - parent.getPaddingBottom();
for (int i = 0; i < parent.getChildCount(); i++) {
View child = parent.getChildAt(i);
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
//params.bottomMargin上一个的item的margin
//(int)ViewCompat.getTranslationY(child) 动画移动的y值
int left = child.getRight() + params.rightMargin + Math.round(ViewCompat.getTranslationX(child));// 得到当前这个控件距离父容器的高度
int right = left + mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(canvas);
}
}
private void drawVertical(Canvas canvas, RecyclerView parent) {
int left = parent.getPaddingLeft() + paddingLeft;
int right = parent.getWidth() - parent.getPaddingRight() - paddingRight;
for (int i = 0; i < parent.getChildCount(); i++) {
View child = parent.getChildAt(i);
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
//params.bottomMargin上一个的item的margin
//(int)ViewCompat.getTranslationY(child) 动画移动的y值
int top = child.getBottom() + params.bottomMargin + Math.round(ViewCompat.getTranslationY(child));// 得到当前这个控件距离父容器的高度
int bottom = top + mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(canvas);
}
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
//1、调用此方法,获取条目的偏移量
//获取条目的偏移量(所有的条目都回调用一次该方法)
if (mOrientation == LinearLayoutManager.VERTICAL) {
int position = parent.getLayoutManager().getPosition(view);
Log.i("wxf", "itemCont:" + parent.getLayoutManager().getItemCount());
Log.i("wxf", "position:" + position);
//如果当前的position是最后一个,就不画
if (position != parent.getLayoutManager().getItemCount() - 1) {
//垂直
outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
}
} else if (mOrientation == LinearLayoutManager.HORIZONTAL) {
// 水平
outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
} else {
//四个方向的偏移值
int right = mDivider.getIntrinsicWidth();
int bottom = mDivider.getIntrinsicHeight();
if (isLastColum(view, parent)) {
//最后一列
right = 0;
}
if (isLastRow(parent)) {
//最后一行
bottom = 0;
}
outRect.set(0, 0, right, bottom);
}
}
private boolean isLastColum(View view, RecyclerView parent) {
if (parent.getLayoutManager() instanceof GridLayoutManager) {
GridLayoutManager layoutManager = (GridLayoutManager) parent.getLayoutManager();
int itemPosition = layoutManager.getPosition(view);
//列
int spanCount = layoutManager.getSpanCount();
if ((itemPosition + 1) % spanCount == 0) {
return true;
}
}
return false;
}
private boolean isLastRow(RecyclerView parent) {
if (parent.getLayoutManager() instanceof GridLayoutManager) {
GridLayoutManager layoutManager = (GridLayoutManager) parent.getLayoutManager();
//int itemPosition = layoutManager.getPosition(view);
//列
int spanCount = layoutManager.getSpanCount();
int childCount = parent.getAdapter().getItemCount();
//最后一行的数量小于spanCount
int lastRowCount = childCount % spanCount;
if (lastRowCount == 0 || lastRowCount < spanCount) {
return true;
}
}
return false;
}
}
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:width="2dp" android:height="2dp"/>
<solid android:color="#ff0000"/>
</shape>