层叠布局

Flutter 中使用 Stack 和 Positioned 这两个组件来配合实现绝对定位。Stack 允许子组件堆叠,而 Positioned 用于根据 Stack 的四个角来确定子组件的位置。

Stack

类似于 CSS 中的 position: relative;

Stack({
  this.alignment = AlignmentDirectional.topStart,
  this.textDirection,
  this.fit = StackFit.loose,
  this.overflow = Overflow.clip,
  List<Widget> children = const <Widget>[],
})

参数

alignment

此参数决定如何去对齐没有定位(没有使用 Positioned)或部分定位的子组件。所谓部分定位,在这里特指没有在某一个轴上定位:left、right 为横轴,top、bottom 为纵轴,只要包含某个轴上的一个定位属性就算在该轴上有定位。

参考 对齐 - Alignment

textDirection

参考 Row 和 Column 的 textDirection

fit

此参数用于确定没有定位的子组件如何去适应 Stack 的大小。

  • StackFit.loose 表示使用子组件的大小
  • StackFit.expand 表示扩伸到 Stack 的大小

overflow

此属性决定如何显示超出 Stack 显示空间的子组件;值为 Overflow.clip 时,超出部分会被剪裁(隐藏),值为 Overflow.visible 时则不会。

  • Overflow.visible 溢出部分可见
  • Overflow.clip 溢出部分隐藏

Positioned

类似于 CSS 中的 position: absolute;

const Positioned({
  Key key,
  this.left,
  this.top,
  this.right,
  this.bottom,
  this.width,
  this.height,
   Widget child,
})

left、top 、right、 bottom 分别代表离 Stack 左、上、右、底四边的距离。width 和 height 用于指定需要定位元素的宽度和高度。注意,Positioned 的 width、height 和其它地方的意义稍微有点区别,此处用于配合 left、top 、right、 bottom 来定位组件,举个例子,在水平方向时,你只能指定 left、right、width 三个属性中的两个,如指定 left 和 width 后,right 会自动算出(left+width),如果同时指定三个属性则会报错,垂直方向同理。

如果是多个Widget定位, 后来者居上 (没有发现类似于css中的z-index属性可以用于调整, 这点很烦)。

如果定位了的元素的子元素也进行了定位, 子元素居上。

注意

Positioned 只能在 Stack 的 children 中使用,在其他的 Widget 中使用会报错。

定位示例

ConstrainedBox(
  constraints: BoxConstraints.expand(),
  child: Stack(
    alignment:Alignment.center , // 指定未定位或部分定位widget的对齐方式
    children: <Widget>[
      Container(child: Text("Hello world",style: TextStyle(color: Colors.white)),
        color: Colors.red,
      ),
      Positioned(
        left: 18.0,
        child: Text("left"),
      ),
      Positioned(
        top: 18.0,
        child: Text("top"),
      ),
      Positioned(
        right: 18.0,
        child: Text("right"),
      ),
      Positioned(
        bottom: 18.0,
        child: Text("bottom"),
      ),
      Positioned(
        left: 40.0,
        right: 40.0,
        bottom: 40.0,
        child: Container(
          decoration: BoxDecoration(
            color: Colors.lime,
          ),
          child: Center(
            child: Text("Hello world"),
          ),
        ),
      ),
    ],
  ),
)

MIT Licensed | Copyright © 2018-present 滇ICP备16006294号

Design by Quanzaiyu | Power by VuePress