本文和大家一起讨论下溢出 效果的六种实现方案。
让我们来看一个效果。蓝色区块溢出红色区块,延伸到上方。
方案一 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 是肯定可以的,因为它的灵活性是最大的。为了方案的完整性,把它也作为方案的一种。
总结了这些多溢出的方案,也是为了让大家了解一下,哪些组件可以溢出,就这样的能力,等遇到问题的时候,会第一时间想起来。