从源码的介绍中可以看出 SizedOverflowBox
组件的特点是:
上一篇介绍的 OverflowBox 组件也可以允许子组件溢出,他们最大的区别在于: OverflowBox
会指定新约束传递给孩子,而 SizedOverflowBox
则将原始约束传递给孩子。
下面是 SizedOverflowBox
组件类的定义
和 构造方法
,可以看出它继承自 SingleChildRenderObjectWidget
。构造时必须传入尺寸 size
参数,并且可以指定对齐方式。
如下,在一个灰色盒子左上角,有一个小红圈,其中心与盒子左上角对齐。可以看出在效果上,小红圈 溢出
了灰色盒子的区域。实现方式是,灰色盒子内部对齐方式 Alignment.topLeft
,SizedOverflowBox
对齐方式 Alignment.center
。
class CustomSizedOverflowBox extends StatelessWidget{
@override
Widget build(BuildContext context) {
return Container(
alignment: Alignment.topLeft,
color: Colors.grey.withAlpha(88),
width: 50,
height: 50,
child: buildChild(),
);
}
Widget buildChild() {
return SizedOverflowBox(
alignment: Alignment.center,
size: Size.zero,
child: Container(
decoration: const BoxDecoration(
color: Colors.red,
shape: BoxShape.circle,
),
width: 15,
height: 15,
),
);
}
}
通过布局可以查看 SizedOverflowBox
的区域信息,如下为 Size(0,0)
,也就是构造时我们传入的尺寸。
当 size
设置为 Size(30,25)
时,效果如下。可见指定的尺寸值就是 SizedOverflowBox
的尺寸,而 SizedOverflowBox
的 alignment
属性就是其内部的对齐方式。
SizedOverflowBox(
alignment: Alignment.center,
size: Size(30,25),
//略同...
);
下面是 SizedOverflowBox#alignment
为 Alignment.topLeft
的效果,可以看出小红球在与左上角对齐。这就是 SizedOverflowBox
的 alignment
和 size
两个属性的作用。
SizedOverflowBox(
alignment: Alignment.topLeft,
size: Size(30,25),
//略同...
);
首先 SizedOverflowBox
会受父级的约束,比如上面的 Container
会施加 [w(50,50) - h(50,50)]
的紧约束,但由于设置了 Container#alignment
属性,内部会使用 Align
组件。这会让 SizedOverflowBox
的约束变为了 [w(0,50) - h(0,50)]
的松散约束,此时 SizedOverflowBox
申请的尺寸为 30*25
,满足约束,则其尺寸为 30*25
。
如果去除了 Container#alignment
属性, [w(50,50) - h(50,50)]
的强约束会直接施加到 SizedOverflowBox
上,即使申请的尺寸为 30*25
,其尺寸也会变为 50*50
。这也间接可以产出 Align
组件可以起到松散约束的效果。
SizedOverflowBox
的特点是:它的约束会直接传递给孩子,不做任何改动。可以看出 Align
施加给 SizedOverflowBox
的 [w(0,50) - h(0,50)]
松散约束,会直接传给小红点。也就是说,虽然小红点可以越界,但它的尺寸仍会受到外层的约束。
SizedOverflowBox
会将自身受到的约束,直接传递给孩子,这也能解释为什么去除了 Container#alignment
属性,SizedOverflowBox
尺寸为 50*50
小红点尺寸也是 50*50
。
即使小红点尺寸申请为 150*150
,由于 [w(0,50) - h(0,50)]
的约束,自身尺寸也将被限制。
SizedOverflowBox
继承自 SingleChildRenderObjectWidget
,内部维护 RenderSizedOverflowBox
渲染对象来实现功能。
可以看出入参的尺寸会为 _requestedSize
属性赋值。
在 performLayout
中,通过当前约束
和请求尺寸
,来决定 RenderSizedOverflowBox
的尺寸。这个渲染对象非常特别,一般来说都是约束
x 向下传递给子节点进行布局,之后子节点向上反馈尺寸。而这里是先确定父节点的尺寸,也就表明它的尺寸并不受子渲染对象影响。如果 child
非空,会对自渲染对象进行布局,传入的是自身的原始约束
。
那本文到这里就结束了,谢谢观看,明天见~