Flutter(62):Layout组件之Stack、Positioned

Flutter教学目录持续更新中

Github源代码持续更新中

1.简介

  • Stack:可以允许其子widget简单的堆叠在一起
  • Positioned:Stack内定位的组件

2.Stack属性

  • alignment = AlignmentDirectional.topStart:只作用于没有使用Positioned或部分定位的子组件
  • textDirection:文本方向
  • fit = StackFit.loose:子组件如何去适应Stack的大小,只作用于没有使用Positioned或部分定位的子组件
  • overflow = Overflow.clip:如何显示超出Stack显示空间的子组件;Overflow.clip:超出部分会被剪裁(隐藏),Overflow.visible时则不会。这个属性未来会被谷歌废弃,由clipBehavior代替,了解一下就行
  • clipBehavior = Clip.hardEdge:
  • children = const []:

3.AlignmentDirectional

这跟Alignment基本上是一样的,只是AlignmentDirectional可以根据TextDirection去改变哪边再是start方向

4.StackFit属性

  • StackFit.loose:使用子组件的大小,只作用于没有使用Positioned的子组件
  • StackFit.expand:扩伸到Stack的大小,只作用于没有使用Positioned的子组件
  • StackFit.passthrough:传递使用Stack的父级约束

5.Clip属性

  • Clip.none:不做处理
  • Clip.hardEdge:裁剪但不应用抗锯齿,速度比none慢一点
  • Clip.antiAlias:裁剪而且抗锯齿,速度慢于hardEdge
  • Clip.antiAliasWithSaveLayer:裁剪、抗锯齿而且有一个缓冲区,速度最慢

6.Positioned属性

  • left:距左
  • top:距上
  • right:距右
  • bottom:距下
  • width:宽度
  • height:高度
    这里需要注意一下left,right,width三个只可以存在两个,top,bottom,height同理

7.使用

7.1我们先来看一下alignment对子控件的影响:

      body: Container(
        constraints: BoxConstraints.expand(),
        padding: EdgeInsets.all(50),
        child: Container(
          color: Colors.blue,
          child: Stack(
            alignment: Alignment.center,
            fit: StackFit.loose,
            clipBehavior: Clip.none,
            children: [
              Container(
                width: 50,
                height: 50,
                color: Colors.red,
              ),
              Positioned(
                bottom: 20,
                child: Container(
                  width: 50,
                  height: 50,
                  color: Colors.green,
                ),
              ),
              Positioned(
                left: 10,
                top: 20,
                child: Container(
                  width: 50,
                  height: 50,
                  color: Colors.amber,
                ),
              ),
            ],
          ),
        ),
      ),
image.png

这里红色正方形没有Positioned定位,则响应alignment定位;绿色正方形有Positioned定位,但是只有bottom无法完全确定位置,所以会结合alignment定位来确定位置;黄色正方形拥有完整的准确的Positioned定位,所以不会响应alignment定位。

7.2接下来我们看一下fit属性对子控件的影响:

7.2.1fit: StackFit.loose

使用子组件的大小,只作用于没有使用Positioned的子组件

      body: Container(
        constraints: BoxConstraints.expand(),
        padding: EdgeInsets.all(50),
        child: Container(
          color: Colors.blue,
          child: Stack(
            alignment: Alignment.center,
            fit: StackFit.loose,
            clipBehavior: Clip.none,
            children: [
              Container(
                width: 50,
                height: 50,
                color: Colors.red,
              ),
              Positioned(
                bottom: 20,
                child: Container(
                  width: 50,
                  height: 50,
                  color: Colors.green,
                ),
              ),
              Positioned(
                left: 10,
                top: 20,
                child: Container(
                  width: 50,
                  height: 50,
                  color: Colors.amber,
                ),
              ),
              Positioned(
                left: 100,
                width: 50,
                top: 20,
                height: 50,
                child: Container(
                  color: Colors.grey,
                ),
              ),
              Positioned(
                left: 10,
                top: 20,
                child: Container(
                  color: Colors.black,
                ),
              ),
            ],
          ),
        ),
      ),
image.png

这种情况下会使用自组件自身的大小,那么像最后一个子组件,没有自己的大小的那就不会显示出来。那么如果最后一个子组件没有Positioned会怎么样呢,那其实又回到了Container自身尺寸调节的问题上来了,他会充满父控件,也就是填满Stack,不会受到fit属性影响。不了解Container自身尺寸调节的的可以看一下:Layout组件之Container

7.2.2fit: StackFit.expand

扩伸到Stack的大小,只作用于没有使用Positioned的子组件

      body: Container(
        constraints: BoxConstraints.expand(),
        padding: EdgeInsets.all(50),
        child: Container(
          color: Colors.blue,
          child: Stack(
            alignment: Alignment.center,
            fit: StackFit.expand,
            clipBehavior: Clip.none,
            children: [
              Container(
                width: 50,
                height: 50,
                color: Colors.red,
              ),
              Positioned(
                bottom: 20,
                child: Container(
                  width: 50,
                  height: 50,
                  color: Colors.green,
                ),
              ),
              Positioned(
                left: 10,
                top: 20,
                child: Container(
                  width: 50,
                  height: 50,
                  color: Colors.amber,
                ),
              ),
              Positioned(
                left: 100,
                width: 50,
                top: 20,
                height: 50,
                child: Container(
                  color: Colors.grey,
                ),
              ),
              Positioned(
                left: 10,
                top: 20,
                child: Container(
                  color: Colors.black,
                ),
              ),
            ],
          ),
        ),
      ),
image.png

可以看到有Positioned不受影响,没有的会直接扩伸到Stack的大小。

7.2.3fit: StackFit.passthrough

传递使用Stack的父级约束,这里我们把父控件换成ListVIew来演示

  _myStackChildren() {
    return [
      Container(
        width: 50,
        height: 50,
        color: Colors.red,
      ),
      Positioned(
        bottom: 20,
        child: Container(
          width: 50,
          height: 50,
          color: Colors.green,
        ),
      ),
      Positioned(
        left: 10,
        top: 20,
        child: Container(
          width: 50,
          height: 50,
          color: Colors.amber,
        ),
      ),
      Positioned(
        left: 100,
        width: 50,
        top: 20,
        height: 50,
        child: Container(
          color: Colors.grey,
        ),
      ),
      Positioned(
        left: 10,
        top: 20,
        child: Container(
          color: Colors.black,
        ),
      ),
      Container(
        width: 60,
        height: 60,
        color: Colors.red.withAlpha(100),
      ),
    ];
  }

      body: ListView(
        children: [
          Stack(
            fit: StackFit.passthrough,
            children: _myStackChildren(),
          ),
        ],
      ),
image.png

7.3Clip

我们增加一个子控件,可以确定这个控件的宽度是会溢出Stack

Positioned(
        left: 30,
        top: 80,
        width: 2000,
        height: 20,
        child: Container(
          color: Colors.black,
        ),
      ),
      body: Container(
        constraints: BoxConstraints.expand(),
        padding: EdgeInsets.all(50),
        child: Container(
          constraints: BoxConstraints(
            minWidth: 100,
            minHeight: 100,
          ),
          color: Colors.blue,
          child: Stack(
            alignment: Alignment.center,
            fit: StackFit.passthrough,
            clipBehavior: Clip.none,
            children: _myStackChildren(),
          ),
        ),
      ),
7.3.1Clip.none
image.png
7.3.2Clip.hardEdge、antiAlias、antiAliasWithSaveLayer
image.png

下一节:Layout组件之IndexedStack

Flutter(63):Layout组件之IndexedStack

Flutter教学目录持续更新中

Github源代码持续更新中

你可能感兴趣的:(Flutter(62):Layout组件之Stack、Positioned)