傻瓜式分割线功能的LinearLayout

我明白,很多读者看到标题后肯定都感到不屑,谷歌的兼容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颜色的分割线,没有做额外定制,有需要的可以做下额外定制。

你可能感兴趣的:(傻瓜式分割线功能的LinearLayout)