我明白,很多读者看到标题后肯定都感到不屑,谷歌的兼容3.0以下的LinearLayoutCompat,以及3.0以上的LinearLayout不都已经实现了带有divider的功能了吗?但是当你们真正用到的时候,你们发现真的如期望的那么好用吗?谷歌的俩控件,在你往线性布局里添加控件,或者隐藏某些控件等等的时候,后边几个divider的绘制的位置并不是期望的位置。具体原因请参见这篇帖子:LinearLayout坑爹的showDividers属性
好了,该控件的核心思想就是在控件dispatchDraw的过程中绘制分割线。支持是否画divider,以及是否画顶部,中间以及底部divider。该控件支持代码控制divider显示方式,也支持xml控制divider显示的方式。具体实现如下:
public class DividerLinearLayout extends LinearLayout {
private Paint paint;
private AttributeSet attrs;
private boolean drawDivider;
private boolean drawTop = true;
private boolean drawMiddle;
private boolean drawBottom = true;
private int dividerLeftMargin;
private int dividerRightMargin;
public DividerLinearLayout(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
this.attrs = attrs;
initPaint();
initView();
}
protected void initView() {
TypedArray ta = null;
try {
ta = getContext().obtainStyledAttributes(attrs, R.styleable.DividerView);
drawDivider = ta.getBoolean(R.styleable.DividerView_drawDivider, false);
drawaTop = ta.getBoolean(R.styleable.DividerView_drawTop, true);
drawMiddle = ta.getBoolean(R.styleable.DividerView_drawMiddle, false);
drawaBottom = ta.getBoolean(R.styleable.DividerView_drawBottom, true);
dividerLeftMargin = ta.getDimensionPixelSize(R.styleable.DividerView_dividerLeftMargin, 0);
dividerRightMargin = ta.getDimensionPixelSize(R.styleable.DividerView_dividerRightMargin, 0);
} finally {
if (null != ta) {
ta.recycle();
}
}
}
@SuppressWarnings("deprecation")
private void initPaint() {
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(getResources().getColor(R.color.color_dddddd));
paint.setStrokeWidth(1);
}
@Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
if (!drawDivider) return;
if (drawTop) {
canvas.drawLine(0, 0, getWidth(), 0, paint);
}
if (drawBottom) {
canvas.drawLine(0, getHeight() - 1, getWidth(), getHeight() - 1, paint);
}
if (drawMiddle) {
int height = 0;
for (int i = 0; i < getChildCount() - 1; i++) {
View child = getChildAt(i);
if (child.getVisibility() == GONE) continue;
if (child.getHeight() == 0) continue;
height += child.getHeight();
canvas.drawLine(dividerLeftMargin, height - 1, getWidth() - dividerRightMargin, height - 1, paint);
}
}
}
protected void setDrawDivider(boolean drawDivider) {
this.drawDivider = drawDivider;
}
public void setDrawTop(boolean drawTop) {
this.drawTop = drawTop;
}
public void setDrawMiddle(boolean drawMiddle) {
this.drawMiddle = drawMiddle;
}
public void setDrawBottom(boolean drawBottom) {
this.drawBottom = drawBottom;
}
public void setDividerLeftMargin(int dividerLeftMargin) {
this.dividerLeftMargin = dividerLeftMargin;
}
public void setDividerRightMargin(int dividerRightMargin) {
this.dividerRightMargin = dividerRightMargin;
}
}
整个代码思想很简单。需要注意的是该控件的divider线的只是默认的1像素#dddddd颜色的分割线,没有做额外定制,有需要的可以做下额外定制。
网友评论