Flutter 基础布局之Stack

Stack意为层叠布局,先添加的控件在底下,后添加的控件在顶上。

Stack的结构体如下:

Stack({
    Key? key,
    this.alignment = AlignmentDirectional.topStart,
    this.textDirection,
    this.fit = StackFit.loose,
    @Deprecated(
      'Use clipBehavior instead. See the migration guide in flutter.dev/go/clip-behavior. '
      'This feature was deprecated after v1.22.0-12.0.pre.',
    )
    this.overflow = Overflow.clip,
    this.clipBehavior = Clip.hardEdge,
    List<Widget> children = const <Widget>[],
  })

我们先看下一段代码:

class _StackState extends State<StackPage> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Container(
          width: MediaQuery.of(context).size.width,
          height: MediaQuery.of(context).size.height,
          alignment: Alignment.center,
          child: Stack(
            children: [
              Container(
                width: 150,
                height: 150,
                color: Colors.amber,
              ),
              Container(
                width: 100,
                height: 100,
                color: Colors.green,
              ),
              Container(
                width: 50,
                height: 50,
                color: Colors.blue,
              ),
            ],
          ),
        ),
      ),
    );
  }
}

效果如下:

我们可以看到Stack的默认行为有两个

1:Stack的大小是最大子控件的大小

2:Stack内部子控件默认居左上

现在我们给Stack加上

alignment: Alignment.center,//居中

可以看到控件居于中心点

下面重点讲Stack中Position的用法

先看Position的结构体

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

left: child距离父控件左边的距离

top: child距离父控件顶部的距离

right: child距离父控件右边的距离

bottom: child距离父控件右边的距离

width: child的宽度

height: child的高度

child:子控件

先看下面一段代码:

class _StackState extends State<StackPage> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Container(
          width: MediaQuery.of(context).size.width,
          height: MediaQuery.of(context).size.height,
          alignment: Alignment.center,
          child: Stack(
            alignment: Alignment.center,
            children: [
              Positioned(
                left: 0,
                child: Container(
                  width: 50,
                  height: 50,
                  color: Colors.amber,
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

我们设置控件距离左边为0,那么控件就紧紧贴在左边

我们现在设置距离右边50

right: 50

看到控件显示位置与预期一致

如果我们同时设置left和right呢

Positioned(
                left: 50,
                right: 50,
                child: Container(
                  width: 50,
                  height: 50,
                  color: Colors.amber,
                ),
              )

可以看到控件虽然自身设置有50的宽度,但是依然被拉伸到符合left和right的宽度,所以同时设置left和right就会强制拉伸控件的宽度

left,right,top,bttom都设置


Positioned(
                left: 50,
                right: 50,
                top: 50,
                bottom: 50,
                child: Container(
                  width: 50,
                  height: 50,
                  color: Colors.amber,
                ),
              )

可以看到高度也被拉伸了

下面我们再看一种情况,Stack里面有2个控件

Stack(
            alignment: Alignment.center,
            children: [
              Positioned(
                child: Container(
                  width: 100,
                  height: 100,
                  color: Colors.amber,
                ),
              ),
              Positioned(
                left: 0,
                child: Container(
                  width: 50,
                  height: 50,
                  color: Colors.green,
                ),
              )
            ],
          )

可以看到绿色的控件不会到屏幕的最左边,而是只到黄色的控件最左边,

这可以看出,Stack里只有一个控件时,该控件可以随意移动,但是有多个控件时,Stack就会计算自身的大小(与最大控件宽度相同),限制里面的控件移动范围

通常情况下,我们Stack里面都不会只有一个控件,而我们想要其中一个控件在全屏范围内定位,那么我们可以这样做,


Stack(
            alignment: Alignment.center,
            children: [
              Container(),
              Positioned(
                child: Container(
                  width: 100,
                  height: 100,
                  color: Colors.amber,
                ),
              ),
              Positioned(
                left: 0,
                child: Container(
                  width: 50,
                  height: 50,
                  color: Colors.green,
                ),
              )
            ],
          )

我们在Stack里添加了一个Container(),Container在没有child时,默认大小会铺满全屏,这时Stack的大小也是全屏了,其中的绿色控件也自然的到了屏幕边上

更多时候我们希望子控件各自出现在我们希望的位置上,并且保持原来的大小

这是我们可以用到Align

代码如下:

class _StackState extends State<StackPage> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Container(
          width: MediaQuery.of(context).size.width,
          height: MediaQuery.of(context).size.height,
          alignment: Alignment.center,
          child: Stack(
            alignment: Alignment.center,
            children: [
              Container(),
              Align(
                alignment: Alignment.topLeft,
                child: Container(
                  width: 50,
                  height: 50,
                  color: Colors.amber,
                ),
              ),
              Align(
                alignment: Alignment.topCenter,
                child: Container(
                  width: 50,
                  height: 50,
                  color: Colors.green,
                ),
              ),
              Align(
                alignment: Alignment.topRight,
                child: Container(
                  width: 50,
                  height: 50,
                  color: Colors.blue,
                ),
              ),
              Align(
                alignment: Alignment.centerLeft,
                child: Container(
                  width: 50,
                  height: 50,
                  color: Colors.lightBlueAccent,
                ),
              ),
              Align(
                alignment: Alignment.center,
                child: Container(
                  width: 50,
                  height: 50,
                  color: Colors.greenAccent,
                ),
              ),
              Align(
                alignment: Alignment.centerRight,
                child: Container(
                  width: 50,
                  height: 50,
                  color: Colors.deepOrangeAccent,
                ),
              ),
              Align(
                alignment: Alignment.bottomLeft,
                child: Container(
                  width: 50,
                  height: 50,
                  color: Colors.deepPurpleAccent,
                ),
              ),
              Align(
                alignment: Alignment.bottomCenter,
                child: Container(
                  width: 50,
                  height: 50,
                  color: Colors.blueGrey,
                ),
              ),
              Align(
                alignment: Alignment.bottomRight,
                child: Container(
                  width: 50,
                  height: 50,
                  color: Colors.pinkAccent,
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

效果如下,主要有9种位置

猜你喜欢

转载自blog.csdn.net/u013474690/article/details/123781488