本文和大家一起讨论下溢出效果的七种实现方案。
让我们来看一个效果。蓝色区块溢出红色区块,延伸到上方。
方案一 SizedOverflowBox
要实现这样的效果很容易想到的就是 SizedOverflowBox,复制下面的代码到 main.dart,运行后查看效果。
Container(
color: Colors.green[400],
width: 100,
height: 100,
alignment: Alignment.topCenter,
child: SizedOverflowBox(
size: Size.zero,
child:
Container(color: Colors.blue, width: 50, height: 50),
)))));
SizedOverflowBox 默认 会把 child 摆放在中间,所以就用了溢出一半的效果。
SizedOverflowBox 会透传 约束给 child,SizedOverflowBox 的 约束 必须是 loose,否则无法让 child 溢出。因为如果是 tight 约束 SizedOverflowBox 和 child 一样大了。
方案二 OverflowBox
实现了同样的效果,但不 SizedOverflowBox 简洁。
Container(
color: Colors.green[400],
width: 100,
height: 100,
child: OverflowBox(
maxHeight: 150,
child:Align(
alignment: Alignment.topCenter,
child:
Container(color: Colors.blue, width: 50, height: 50))
))
OverflowBox 会在父级允许的范围内尽可能的大。在本例中 OverflowBox 的大小为
size(100,100)
。
布局解说
- OverflowBox 会充满绿色 container,并允许 child 可以达到 150 height
- Align 高度 150,OverflowBox 默认居中摆放 Align,向上溢出 25,向下溢出 25。
- Align 顶部分摆放 blue Container,效果上正好向上溢出 25。
方案三 stack
虽然在效果是一样的,但 stack 的本意是层叠。和 web 中 绝对定位差不多。
Stack(
clipBehavior: Clip.none,
alignment: Alignment.center,
children: [
Container(
color: Colors.green[400],
width: 100,
height: 100,),
Positioned(
top:-25,
child: Container(color: Colors.blue, width: 50, height: 50))
]
)
布局解说
- stack 和 green container 一样大。
- stack 根据 top:-25 ,确定上下位置,再根据 alignment: Alignment.center,确定左右位置,
clipBehavior: Clip.none
允许溢出,最终效果就是左右居中,向上溢出 25。
stack 在只有 positioned 定位元素的情况下无尽量大。在本例中受到的是父级的 loose 约束,最终 size(100,100
Positioned left:0,right:0
,相当于指定了 Positioned 宽度 100%,并传一个 tight 约束给 Align, Align把 tight约束转化为 loose 约束,蓝色container 最终 宽度 50,左右居中。因为 stack设置为 允许溢出,所以高度显示为 200。
方案四 transform
Container(
color: Colors.green[400],
width: 100,
height: 100,
alignment:Alignment.topCenter,
child:Transform.translate(
offset:const Offset(0,-25),
child:
Container(color: Colors.blue, width: 50, height: 50))
)
方案五 FitteBbox
Container(
color: Colors.green[400],
width: 100,
height: 100,
child:FittedBox(
fit: BoxFit.none,
child:Container(
alignment: Alignment.topCenter,
height: 150,
child:Container(color: Colors.blue, width: 50, height: 50)))
)
布局解说
- FittedBox 放飞 child ,高度 150
- FittedBox 默认居中摆放 child ,向上溢出 25。
- FittedBox’ child 在顶部居中 blue container ,最终效果就是向上溢出 20,左右居中。
方案六 Align
Container(
color: Colors.green[400],
width: 100,
height: 100,
alignment: Alignment(0, -2),
child: Container(color: Colors.blue, width: 50, height: 50),
)
这不用解说了,这应该是最简单的方案了。如果对 Alignment 不熟悉可以看这里 Flutter Align 详解
方案七 CustomSingleChildLayout
用 CustomSingleChildLayout 是肯定可以的,因为它的灵活性是最大的。如果有兴趣可以看原文介绍。
总结了这些多溢出的方案,也是为了让大家了解一下,哪些组件可以溢出,就这样的能力,等遇到问题的时候,会第一时间想起来。
其实还有很多组件可以有溢出的效果,如果都算上的话,远不止 7 种。比如 BaseLine,FractionalTranslation 等。