上一篇从树的分支这个角度对代码进行了拓展优化,使其能够支持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项目中阅读完整代码。
下一篇讲解如何通过策略模式、装饰模式和工厂方法模式来进一步优化代码。