一、先看效果:
二、簡述實現方法
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>