package com.doumee.lib_coremodel.binding.viewadapter.recyclerview;
|
|
import android.content.Context;
|
import android.content.res.TypedArray;
|
import android.graphics.Canvas;
|
import android.graphics.Rect;
|
import android.graphics.drawable.Drawable;
|
import android.view.View;
|
|
import androidx.recyclerview.widget.RecyclerView;
|
|
/**
|
* Created by goldze on 2017/6/16.
|
*/
|
public class DividerLine extends RecyclerView.ItemDecoration {
|
private static final String TAG = DividerLine.class.getCanonicalName();
|
//默认分隔线厚度为2dp
|
private static final int DEFAULT_DIVIDER_SIZE = 1;
|
//控制分隔线的属性,值为一个drawable
|
private static final int ATTRS[] = {android.R.attr.listDivider};
|
//divider对应的drawable
|
private Drawable dividerDrawable;
|
private Context mContext;
|
private int dividerSize;
|
//默认为null
|
private LineDrawMode mMode = null;
|
|
/**
|
* 分隔线绘制模式,水平,垂直,两者都绘制
|
*/
|
public enum LineDrawMode {
|
HORIZONTAL, VERTICAL, BOTH
|
}
|
|
public DividerLine(Context context) {
|
mContext = context;
|
//获取样式中对应的属性值
|
TypedArray attrArray = context.obtainStyledAttributes(ATTRS);
|
dividerDrawable = attrArray.getDrawable(0);
|
attrArray.recycle();
|
}
|
|
public DividerLine(Context context, LineDrawMode mode) {
|
this(context);
|
mMode = mode;
|
}
|
|
public DividerLine(Context context, int dividerSize, LineDrawMode mode) {
|
this(context, mode);
|
this.dividerSize = dividerSize;
|
}
|
|
public int getDividerSize() {
|
return dividerSize;
|
}
|
|
public void setDividerSize(int dividerSize) {
|
this.dividerSize = dividerSize;
|
}
|
|
public LineDrawMode getMode() {
|
return mMode;
|
}
|
|
public void setMode(LineDrawMode mode) {
|
mMode = mode;
|
}
|
|
/**
|
* Item绘制完毕之后绘制分隔线
|
* 根据不同的模式绘制不同的分隔线
|
*
|
* @param c
|
* @param parent
|
* @param state
|
*/
|
@Override
|
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
|
super.onDrawOver(c, parent, state);
|
if (getMode() == null) {
|
throw new IllegalStateException("assign LineDrawMode,please!");
|
}
|
switch (getMode()) {
|
case VERTICAL:
|
drawVertical(c, parent, state);
|
break;
|
case HORIZONTAL:
|
drawHorizontal(c, parent, state);
|
break;
|
case BOTH:
|
drawHorizontal(c, parent, state);
|
drawVertical(c, parent, state);
|
break;
|
}
|
}
|
|
/**
|
* 绘制垂直分隔线
|
*
|
* @param c
|
* @param parent
|
* @param state
|
*/
|
private void drawVertical(Canvas c, RecyclerView parent, RecyclerView.State state) {
|
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 = getDividerSize() == 0 ? left + dip2px(mContext, DEFAULT_DIVIDER_SIZE) : left + getDividerSize();
|
dividerDrawable.setBounds(left, top, right, bottom);
|
dividerDrawable.draw(c);
|
}
|
}
|
|
/**
|
* 绘制水平分隔线
|
*
|
* @param c
|
* @param parent
|
* @param state
|
*/
|
private void drawHorizontal(Canvas c, RecyclerView parent, RecyclerView.State state) {
|
int childCount = parent.getChildCount();
|
for (int i = 0; i < childCount; i++) {
|
//分别为每个item绘制分隔线,首先要计算出item的边缘在哪里,给分隔线定位,定界
|
final View child = parent.getChildAt(i);
|
//RecyclerView的LayoutManager继承自ViewGroup,支持了margin
|
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
|
//child的左边缘(也是分隔线的左边)
|
final int left = child.getLeft() - params.leftMargin;
|
//child的底边缘(恰好是分隔线的顶边)
|
final int top = child.getBottom() + params.topMargin;
|
//child的右边(也是分隔线的右边)
|
final int right = child.getRight() - params.rightMargin;
|
//分隔线的底边所在的位置(那就是分隔线的顶边加上分隔线的高度)
|
final int bottom = getDividerSize() == 0 ? top + dip2px(mContext, DEFAULT_DIVIDER_SIZE) : top + getDividerSize();
|
dividerDrawable.setBounds(left, top, right, bottom);
|
//画上去
|
dividerDrawable.draw(c);
|
}
|
}
|
|
@Override
|
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
|
super.getItemOffsets(outRect, view, parent, state);
|
// outRect.bottom = getDividerSize() == 0 ? dip2px(mContext, DEFAULT_DIVIDER_SIZE) : getDividerSize();
|
}
|
|
/**
|
* 将dip或dp值转换为px值,保证尺寸大小不变
|
*
|
* @param dipValue
|
* @param context(DisplayMetrics类中属性density)
|
* @return
|
*/
|
public static int dip2px(Context context, float dipValue) {
|
float scale = context.getResources().getDisplayMetrics().density;
|
return (int) (dipValue * scale + 0.5f);
|
}
|
}
|