本系列教程基于Flutter widget, 意在为Flutter 入门提供基础建设. 重点在讲解widget 的 用法,参数以及扩展.
适宜人群: 入门


引子

本次讲解的是 Flutter 组件中的 Padding , Padding 往往不会直接使用. 更多的情况是使用 Container 作为容器, 而 Padding 组件提供了 margin 、 padding 的功能.那么, padding 作为边距提供者. 本身作了哪些处理以至于可以增加组件的内外边距. 接下来, 让我们一同分析分析 Padding作为常用的边距组件, 内部有哪些实现吧!

用法

首先, 我们创建一个如下结构的 Padding 组件



结构很简单, 一个大点的蓝色包裹着小一点的橘色色块. 结果如图:


在图片中, Padding 实际上就是蓝色部分. 我们可以通过 Layout Explorer 分析一下它的结构. 可以看出, 整体上与我们在代码中描述的结构一样. 内部的 SizedBox 为 100*100 的盒子, 四周分别有10的间距. 也就是说 Padding 这一层级实际上占用的大小为 120*120. 而 Padding 真正绘制的部分在 RenderPadding 中. 我们进一步分析分析 RenderPadding.

202212071120.png


解析

RenderPadding 是 Padding 继承于 SingleChildRenderObjectWidget 用于描述 RenderObject的信息. 它负责最终的绘制、测量以及限制大小. 我们重点关注它关于布局的部分:
image
整体的流程从 _resolve 开始, 首先解析传入的 padding 传入的值. 这里会根据文字的方向, 如果是 ltr , 那么解析出来的 _resolvedPadding 左边便为左间距. 反之是rtl, 那么右边则为左间距.

1
2
3
4
5
6
void _resolve() {
if (_resolvedPadding != null)
return;
_resolvedPadding = padding.resolve(textDirection);
assert(_resolvedPadding!.isNonNegative);
}

我们在 _resolve 之后, 会根据 Padding 是否有 child 而走不同的路.


child 为空

当我们没有 child 的时候, 我们的约束将尽可能的适应约束的大小以及 Padding 的大小. 它通过 constrain 函数, 将我们解析出来的 _resolvedPadding 转换成 Size , 即左右间距之合为宽, 上下间距之合为高.

1
2
3
4
return constraints.constrain(Size(
_resolvedPadding!.left + _resolvedPadding!.right,
_resolvedPadding!.top + _resolvedPadding!.bottom,
));

在 constrain 函数中, 我们根据约束以及解析出来的 size 去计算当前的 Padding 应该占据的 size 大小.
image


child 不为空

当 child 不为空的时候, 我们才需要真正的去布局 child. 既然需要 Padding, 那么 child 的约束也就需要减去给予的 padding . 然后就可以将减完的约束重布局 child.

1
2
final BoxConstraints innerConstraintsconstraints.deflate(_resolvedPadding!);
child!.layout(innerConstraints, parentUsesSize: true);

最后, 我们同步一下盒约束就完成了.


结语

这里是WeninerIo,如果你对这次的技术分享感兴趣或者有什么疑惑, 不妨在评论区留言或私信.
或许这次的分享不是你期待的点, 那就点个关注吧! 下次也许就是适合你的点呢?

Thanks for meeting ! ! !

image