自定义布局之树形布局(八):优化支持Padding

上一篇从树的分支这个角度对代码进行了拓展优化,使其能够支持n叉树有效性的检查。本篇来讲解如何更好地支持树形布局的Padding。

View是不支持Padding的,而ViewGroup是支持Padding的。在给属性布局添加Padding参数时“意外地”发现了一个Bug。
在这里插入图片描述
可以看到继承自ViewGroup的树形布局本身是可以让子控件支持Padding的,但是绘制的连接线却不支持Padding。这是因为在绘制连接线的时候并没有把Padding考虑进去。

这里首先需要了解三个关键的方法,save,restore及clipRect。
clipRect用于剪切画布,而save和restore需要成对使用。save方法用于保存画布的各种参数,画布经过了平移、旋转、裁剪等一系列改动后,可以通过restore方法恢复到save时的状态。

了解了它们后,接下来在原有的基础上对连接线绘制进行修改,代码如下:

protected void onDrawConnectLine(Canvas canvas){
		//1.1
        canvas.save();

        int paddingLeft = getPaddingLeft();
        int paddingRight = getPaddingRight();
        int paddingTop = getPaddingTop();
        int paddingBottom = getPaddingBottom();

        int scrollX = getScrollX();
        int scrollY = getScrollY();

        mPaddingClipRect.left = scrollX + paddingLeft;
        mPaddingClipRect.top = scrollY + paddingTop;
        mPaddingClipRect.right = scrollX + getWidth() - paddingRight;
        mPaddingClipRect.bottom = scrollY + getHeight() - paddingBottom;

		//2
        canvas.clipRect(mPaddingClipRect);

        View root = getChildAt(0);
        mStartRect.left = root.getLeft();
        mStartRect.right = root.getRight();
        mStartRect.top = root.getTop();
        mStartRect.bottom = root.getBottom();

        for(int i = 1;i < getChildCount();i++){
            View child = getChildAt(i);
            if(child.getVisibility() == View.GONE){
                continue;
            }
            mEndRect.left = child.getLeft();
            mEndRect.right = child.getRight();
            mEndRect.top = child.getTop();
            mEndRect.bottom = child.getBottom();
            mLineDrawer.onDrawLine(canvas,mPaint,mStartRect,mEndRect,mTreeDirection);
        }
		//1.2
        canvas.restore();
    }

代码1.1和1.2需要成对出现,在它们之间可以对画布的各种参数进行改动。

因为树形布局在解锁后是可以拖拽的,所以在布局拖拽的时候,裁剪的范围也得跟着移动。

修改好了再来看看效果。
在这里插入图片描述
如此一来,树形布局就完全支持Padding了。

最后

本次优化对代码改动较多,感兴趣的朋友可以到Github项目中阅读完整代码。

下一篇讲解如何通过策略模式、装饰模式和工厂方法模式来进一步优化代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值