上面写了一篇自定义分割线,重在理解分割线的绘制原理,这篇侧重于项目实战中应用。
1.创建继承ItemDecoration
构造创建,这次使用attrs 的方式
private Drawable mDivider;
private int[] attrs = new int[]{
android.R.attr.listDivider
};
public DividerGridItemDecoration(Context context) {
TypedArray typedArray = context.obtainStyledAttributes(attrs);
mDivider = typedArray.getDrawable(0);
typedArray.recycle();
}
在清单文件中配置主题
<activity android:name=".fenline.RecyclerViewActivity"
android:theme="@style/AppTheme"/>
在主题中配置listDivider属性
<!-- Base application theme. -->
<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/list_item_divider</item>
</style>
然而list_item_divider自己绘制的分割线样式,举个例子:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<size android:height="0.5dp"
android:width="0.5dp"
/>
<solid android:color="@color/login_color" />
</shape>
2.onDraw方法区分逻辑
onDraw方法区分是水平还是竖直分割线
@Override
public void onDraw(Canvas c, RecyclerView parent, State state) {
drawVertical(c, parent);
drawHorizontal(c, parent);
}
绘制竖直分割线方法
private void drawVertical(Canvas c, RecyclerView parent) {
//绘制垂直间隔线(垂直的矩形)
int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
View child = parent.getChildAt(i);
RecyclerView.LayoutParams params = (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(c);
}
}
绘制水平分割线方法
private void drawHorizontal(Canvas c, RecyclerView parent) {
// 绘制水平间隔线
int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
View child = parent.getChildAt(i);
RecyclerView.LayoutParams params = (LayoutParams) child.getLayoutParams();
int left = child.getLeft() - params.leftMargin;
int right = child.getRight() + params.rightMargin + mDivider.getIntrinsicWidth();
int top = child.getBottom() + params.bottomMargin;
int bottom = top + mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}
3.getItemOffsets逻辑实现
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, State state) {
// 四个方向的偏移值
int right = mDivider.getIntrinsicWidth();
int bottom = mDivider.getIntrinsicHeight();
int position = ((LayoutParams) view.getLayoutParams()).getViewLayoutPosition();
if (isLastColumn(position, parent)) {// 是否是最后一列
right = 0;
}
if (isLastRow(position, parent)) {// 是否是最后一行
bottom = 0;
}
outRect.set(0, 0, right, bottom);
}
其他方法
/**
* 是否是最后一列
*/
public boolean isLastColumn(int itemPosition, RecyclerView parent) {
int spanCount = getSpanCount(parent);
if ((itemPosition + 1) % spanCount == 0) {
return true;
} else {
return false;
}
}
/**
* 是否是最后一行
*/
public boolean isLastRow(int itemPosition, RecyclerView parent) {
int spanCount = getSpanCount(parent);
int childCount = parent.getAdapter().getItemCount();
int rowNumber = childCount % spanCount == 0 ? childCount / spanCount : (childCount / spanCount) + 1;
if (itemPosition > ((rowNumber - 1) * spanCount - 1)) {
return true;
}
return false;
}
/**
* 获取一行有多少列
*/
public int getSpanCount(RecyclerView parent) {
RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
if (layoutManager instanceof GridLayoutManager) {
// 获取一行的spanCount
GridLayoutManager gridLayoutManager = (GridLayoutManager) layoutManager;
int spanCount = gridLayoutManager.getSpanCount();
return spanCount;
}
return 1;
}
4.使用
使用方法很简单,只需添加如下这句:
mRecyclerView.addItemDecoration(new DividerGridItemDecoration(this));