Skip to content

层叠布局(Stack & Positioned)

Stack

dart
Stack({
  this.alignment = AlignmentDirectional.topStart,
  this.textDirection,
  this.fit = StackFit.loose,
  this.overflow = Overflow.clip,
  List<Widget> children = const <Widget>[],
})
  • alignment:此参数决定如何去对齐没有定位(没有使用Positioned)或部分定位的子组件
  • textDirection:和RowWraptextDirection功能一样,都用于确定alignment对齐的参考系
  • fit:此参数用于确定没有定位的子组件如何去适应Stack的大小。StackFit.loose表示使用子组件的大小,StackFit.expand表示扩伸到Stack的大小
  • overflow:此属性决定如何显示超出Stack显示空间的子组件;值为Overflow.clip时,超出部分会被剪裁(隐藏),值为Overflow.visible 时则不会

Positioned

dart
const Positioned({
  Key? key,
  this.left, 
  this.top,
  this.right,
  this.bottom,
  this.width,
  this.height,
  required Widget child,
})
  • lefttoprightbottom分别代表离Stack左、上、右、底四边的距离
  • widthheight用于指定需要定位元素的宽度和高度

在水平方向时,你只能指定leftrightwidth三个属性中的两个,如指定leftwidth后,right会自动算出(left+width),如果同时指定三个属性则会报错,垂直方向同理

例子1

dart
ConstrainedBox(
  constraints: BoxConstraints.expand(),
  child: Stack(
    alignment: Alignment.center,
    children: [
      Text('1', style: TextStyle(fontSize: 40)),
      Positioned(
        left: 18,
        child: Text('2', style: TextStyle(fontSize: 40)),
      ),
      Positioned(
        top: 18,
        child: Text('3', style: TextStyle(fontSize: 40)),
      ),
    ],
  ),
)
  1. 第一个子文本组件没有指定定位,并且alignment值为Alignment.center,所以它会居中显示

  2. 第二个子文本组件只指定了水平方向的定位(left),所以属于部分定位,所以在垂直方向的对齐方式则会按照alignment指定的对齐方式对齐,即垂直方向居中

  3. 与二同理

例子2

dart
ConstrainedBox(
  constraints: BoxConstraints.expand(),
  child: Stack(
    alignment: Alignment.center,
    fit: StackFit.expand,
    children: [
      Positioned(
        left: 18,
        child: Text('1', style: TextStyle(fontSize: 40)),
      ),
      Container(
        child: Text('2', style: TextStyle(fontSize: 40)),
        color: Colors.pink,
      ),
      Positioned(
        top: 18,
        child: Text('3', style: TextStyle(fontSize: 40)),
      ),
    ],
  ),
)

由于第二个子文本组件没有定位,所以fit属性会对它起作用,就会占满Stack

由于Stack子元素是堆叠的,所以第一个子文本组件被第二个遮住了,而第三个在最上层,所以可以正常显示