美文网首页
傻瓜式分割线功能的LinearLayout

傻瓜式分割线功能的LinearLayout

作者: android_hcf | 来源:发表于2017-06-16 15:53 被阅读37次

    我明白,很多读者看到标题后肯定都感到不屑,谷歌的兼容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

          本文链接:https://www.haomeiwen.com/subject/nwqmqxtx.html