recyclerview可以通過addItemDecoration()方法實現添加自定義分割線的功能。比如需要實現如下圖功能
首先自己定義類繼承自RecyclerView.ItemDecoration
public class MyDividerDecoration extends RecyclerView.ItemDecoration {
private static final int[] ATTRS = new int[]{
android.R.attr.listDivider
};
/**
* 用於繪製間隔樣式
*/
private Drawable mDivider;
public MyDividerDecoration(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) {
// 繪製間隔,每一個item,繪製右邊和下方間隔樣式
int childCount = parent.getChildCount();
int spanCount = ((GridLayoutManager)parent.getLayoutManager()).getSpanCount();
int orientation = ((GridLayoutManager)parent.getLayoutManager()).getOrientation();
boolean isDrawHorizontalDivider = true;
boolean isDrawVerticalDivider = true;
int extra = childCount % spanCount;
extra = extra == 0 ? spanCount : extra;
for(int i = 0; i < childCount; i++) {
isDrawVerticalDivider = true;
isDrawHorizontalDivider = true;
// 如果是豎直方向,最右邊一列不繪製豎直方向的間隔
if(orientation == OrientationHelper.VERTICAL && (i + 1) % spanCount == 0) {
isDrawVerticalDivider = false;
}
// 如果是豎直方向,最後一行不繪製水平方向間隔
if(orientation == OrientationHelper.VERTICAL && i >= childCount - extra) {
isDrawHorizontalDivider = false;
}
// 如果是水平方向,最下面一行不繪製水平方向的間隔
if(orientation == OrientationHelper.HORIZONTAL && (i + 1) % spanCount == 0) {
isDrawHorizontalDivider = false;
}
// 如果是水平方向,最後一列不繪製豎直方向間隔
if(orientation == OrientationHelper.HORIZONTAL && i >= childCount - extra) {
isDrawVerticalDivider = false;
}
if(isDrawHorizontalDivider) {
drawHorizontalDivider(c, parent, i);
}
if(isDrawVerticalDivider) {
drawVerticalDivider(c, parent, i);
}
}
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
int spanCount = ((GridLayoutManager) parent.getLayoutManager()).getSpanCount();
int orientation = ((GridLayoutManager)parent.getLayoutManager()).getOrientation();
int position = parent.getChildLayoutPosition(view);
if(orientation == OrientationHelper.VERTICAL && (position + 1) % spanCount == 0) {
outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
return;
}
if(orientation == OrientationHelper.HORIZONTAL && (position + 1) % spanCount == 0) {
outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
return;
}
outRect.set(0, 0, mDivider.getIntrinsicWidth(), mDivider.getIntrinsicHeight());
}
/**
* 繪製豎直間隔線
*
* @param canvas
* @param parent
* 父佈局,RecyclerView
* @param position
* irem在父佈局中所在的位置
*/
private void drawVerticalDivider(Canvas canvas, RecyclerView parent, int position) {
final View child = parent.getChildAt(position);
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
.getLayoutParams();
final int top = child.getTop() - params.topMargin;
final int bottom = child.getBottom() + params.bottomMargin + mDivider.getIntrinsicHeight();
final int left = child.getRight() + params.rightMargin;
final int right = left + mDivider.getIntrinsicWidth();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(canvas);
}
/**
* 繪製水平間隔線
*
* @param canvas
* @param parent
* 父佈局,RecyclerView
* @param position
* item在父佈局中所在的位置
*/
private void drawHorizontalDivider(Canvas canvas, RecyclerView parent, int position) {
final View child = parent.getChildAt(position);
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
.getLayoutParams();
final int top = child.getBottom() + params.bottomMargin;
final int bottom = top + mDivider.getIntrinsicHeight();
final int left = child.getLeft() - params.leftMargin;
final int right = child.getRight() + params.rightMargin + mDivider.getIntrinsicWidth();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(canvas);
}
}
其次在drawable文件夾下新建xml文件定義間隔線寬度與顏色
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<solid android:color="@color/bg_gray"/>
<size android:height="2dp" android:width="2dp"/>
</shape>
然後在styles.xml中定義的應用主題裏替換掉listdivider屬性。 <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="android:listDivider">@drawable/my_divider</item>
</style>
接下來就是調用了
recyclerview.addItemDecoration(new MyDividerDecoration(this));
到這裏添加分割線的功能就實現了