RecyclerView設(shè)置分割線
RecyclerView的分割線去設(shè)置布局器净?太low了!
RecyclerView提供了一個(gè)類設(shè)置分割線鹤树,我們需繼承 RecyclerView.ItemDecoration
然后繪制分割線。
代碼如下:
public class DividerItemDecoration extends RecyclerView.ItemDecoration {
/**
* RecyclerView布局方向,設(shè)置默認(rèn)的
*/
private int mOrientation = LinearLayoutManager.VERTICAL;
/**
* 分割線寬度
*/
private int mItemSize = 1;
/**
* 畫筆
*/
private Paint mPaint;
private Drawable mDivider;
private static final int[] ATTRS = new int[]{
android.R.attr.listDivider
};
public DividerItemDecoration(Context context, int orientation) {
this.mOrientation = orientation;
if (orientation != LinearLayoutManager.VERTICAL && orientation != LinearLayoutManager.HORIZONTAL) {
throw new IllegalArgumentException("請(qǐng)傳入正確參數(shù)");
}
mItemSize = (int) TypedValue.applyDimension(mItemSize, TypedValue.COMPLEX_UNIT_DIP, context.getResources().getDisplayMetrics());
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setColor(Color.BLUE);
/*設(shè)置填充*/
mPaint.setStyle(Paint.Style.FILL);
}
public DividerItemDecoration(Context context, int orientation,String na) {
final TypedArray a = context.obtainStyledAttributes(ATTRS);
mDivider = a.getDrawable(0);
a.recycle();
}
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
super.onDraw(c, parent, state);
if (mOrientation == LinearLayoutManager.VERTICAL) {
drawVertical(c, parent);
} else {
drawHorizontal(c, parent);
}
}
/**
* 繪制縱向 item 分割線
*
* @param canvas
* @param parent
*/
private void drawVertical(Canvas canvas, RecyclerView parent) {
final int left = parent.getPaddingLeft();
final int right = parent.getMeasuredWidth() - parent.getPaddingRight();
final int childSize = parent.getChildCount();
for (int i = 0; i < childSize; i++) {
final View child = parent.getChildAt(i);
RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) child.getLayoutParams();
final int top = child.getBottom() + layoutParams.bottomMargin;
final int bottom = top + mItemSize;
if (mPaint==null){
canvas.drawRect(left, top, right, bottom, mPaint);
}else {
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(canvas);
}
}
}
/**
* 繪制橫向 item 分割線
*
* @param canvas
* @param parent
*/
private void drawHorizontal(Canvas canvas, RecyclerView parent) {
final int top = parent.getPaddingTop();
final int bottom = parent.getMeasuredHeight() - parent.getPaddingBottom();
final int childSize = parent.getChildCount();
for (int i = 0; i < childSize; i++) {
final View child = parent.getChildAt(i);
RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) child.getLayoutParams();
final int left = child.getRight() + layoutParams.rightMargin;
final int right = left + mItemSize;
if (mPaint==null){
canvas.drawRect(left, top, right, bottom, mPaint);
}else {
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(canvas);
}
}
}
//設(shè)置偏移量
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
if (mOrientation == LinearLayoutManager.VERTICAL) {
outRect.set(0, 0, 0, mItemSize);
} else {
outRect.set(0, 0, mItemSize, 0);
}
}
}
首先獲取到布局的方向至扰,根據(jù)方向繪制間隔 也就是在onDraw方法中。先判斷后執(zhí)行资锰。
繪制間隔線有兩種方法一種是畫筆直接畫敢课,一種是自定義Drawable繪制。這里給了兩個(gè)構(gòu)造方法绷杜,兩個(gè)參數(shù)的是畫筆
三個(gè)參數(shù)的是Drawable直秆,第三個(gè)參數(shù)直接傳null就行了。
最后要設(shè)置偏移量鞭盟,在getItemOffsets中圾结。
上面只是線性布局的分割線的設(shè)置,網(wǎng)格布局的分割線怎么設(shè)置呢齿诉?
網(wǎng)格布局的分割線則比較麻煩筝野,直接上代碼
public class DividerGridItemDecoration extends RecyclerView.ItemDecoration {
private static final int[] ATTRS = new int[]{android.R.attr.listDivider};
private Drawable mDivider;
public DividerGridItemDecoration(Context context) {
final TypedArray a = context.obtainStyledAttributes(ATTRS);
mDivider = a.getDrawable(0);
a.recycle();
}
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
drawHorizontal(c, parent);
drawVertical(c, parent);
}
private int getSpanCount(RecyclerView parent) {
// 列數(shù)
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();
}
return spanCount;
}
/**
* 繪制縱向分割線
*
*/
public void drawHorizontal(Canvas c, RecyclerView parent) {
int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = parent.getChildAt(i);
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
.getLayoutParams();
final int left = child.getLeft() - params.leftMargin;
final int right = child.getRight() + params.rightMargin
+ mDivider.getIntrinsicWidth();
final int top = child.getBottom() + params.bottomMargin;
final int bottom = top + mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}
public void drawVertical(Canvas c, RecyclerView parent) {
final int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = parent.getChildAt(i);
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
.getLayoutParams();
final int top = child.getTop() - params.topMargin;
final int bottom = child.getBottom() + params.bottomMargin;
final int left = child.getRight() + params.rightMargin;
final int right = left + mDivider.getIntrinsicWidth();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}
private boolean isLastColum(RecyclerView parent, int pos, int spanCount,
int childCount) {
RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
if (layoutManager instanceof GridLayoutManager) {
if ((pos + 1) % spanCount == 0) {// 如果是最后一列,則不需要繪制右邊
return true;
}
} else if (layoutManager instanceof StaggeredGridLayoutManager) {
int orientation = ((StaggeredGridLayoutManager) layoutManager)
.getOrientation();
if (orientation == StaggeredGridLayoutManager.VERTICAL) {
if ((pos + 1) % spanCount == 0) {// 如果是最后一列粤剧,則不需要繪制右邊
return true;
}
} else {
childCount = childCount - childCount % spanCount;
if (pos >= childCount)// 如果是最后一列歇竟,則不需要繪制右邊
return true;
}
}
return false;
}
private boolean isLastRaw(RecyclerView parent, int pos, int spanCount, int childCount) {
RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
if (layoutManager instanceof GridLayoutManager) {
childCount = childCount - childCount % spanCount;
if (pos >= childCount)// 如果是最后一行,則不需要繪制底部
return true;
} else if (layoutManager instanceof StaggeredGridLayoutManager) {
int orientation = ((StaggeredGridLayoutManager) layoutManager)
.getOrientation();
// StaggeredGridLayoutManager 且縱向滾動(dòng)
if (orientation == StaggeredGridLayoutManager.VERTICAL) {
childCount = childCount - childCount % spanCount;
// 如果是最后一行抵恋,則不需要繪制底部
if (pos >= childCount)
return true;
} else { // StaggeredGridLayoutManager 且橫向滾動(dòng)
// 如果是最后一行途蒋,則不需要繪制底部
if ((pos + 1) % spanCount == 0) {
return true;
}
}
}
return false;
}
@Override
public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) {
int spanCount = getSpanCount(parent);
int childCount = parent.getAdapter().getItemCount();
if (isLastRaw(parent, itemPosition, spanCount, childCount)) {// 如果是最后一列,則不需要顯示右邊分割線
outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
} else if (isLastColum(parent, itemPosition, spanCount, childCount)) {// 如果是最后一行馋记,則不需要顯示底部分割線
outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
} else {
outRect.set(0, 0, mDivider.getIntrinsicWidth(),
mDivider.getIntrinsicHeight());
}
}
}
在onDraw中有連個(gè)方法:drawHorizontal 與drawVertical分別是繪制縱向分割線 繪制橫向分割線
最后設(shè)置偏移量getItemOffsets這里就要做判斷是否顯示分割線
isLastRaw判斷如果是最后一列号坡,則不需要顯示右邊分割線
isLastColum如果是最后一行,則不需要顯示底部分割線
使用:
recyclerView.addItemDecoration(new DividerGridItemDecoration(this));