Flutter Widget之Stack

2022-09-11  本文已影响0人  走在路上的日子

Stack一般与Positioned配合使用,在Flutter中我们称之为层叠布局,顾名思义,它允许子Widget按照代码顺序堆叠起来。并可以利用其相关属性调整其子Widget的位置。看如下代码:

Container (
  width: 300,
  height: 300,
  color: Colors.blue,
  child: Stack(
    children: [
      Positioned(child: Text("顶部居左"), left: 18,),
      Positioned(child: Text("底部居左"), left: 18, bottom: 18,),
      Positioned(child: Text("顶部居右"), right: 18 top: 18,),
      Positioned(child: Text("底部居右"), right: 18, bottom: 18,),
    ],
  ),
);

运行效果:


通过Positioned的left,top,right,bottom属性;在Stack中绝对定位到相应位置

Container (
  width: 300,
  height: 300,
  color: Colors.blue,
  child: Stack(
    // 未被Positioned包括或没有设置位置的Widget对齐方式
    alignment: Alignment.center,
    children: [
      Text("没有Positioned"),
      Positioned(child: Text("居中")),
      Positioned(child: Text("顶部居左"), left: 18,),
      Positioned(child: Text("底部居左"), left: 18, bottom: 18,),
      Positioned(child: Text("顶部居右"), right: 18 top: 18,),
      Positioned(child: Text("底部居右"), right: 18, bottom: 18,),
    ],
  ),
);

运行效果:


我们设置了alignment值为 Alignment.center。那么居左的Text,现在在垂直方向上居中了。没有设置上下左右间距的居中Widget和没有被Positioned包括的Text与相对于父Widget居中了。

enum StackFit {
   // 使用子Widget 自身的大小
   loose,
   // 使子widget与stack大小一致
   expand,
   // stack的父widget的布局大小约束无修改的传递给 Stack 的子Widget
   passthrough,
}

我们来看一下:loose

Container(
  width: 300,
  height: 300,
  color: Colors.blue,
  child: Stack(
    fit: StackFit.loose,
    children: [
      Container(
          width: 200,
          height: 20,
          color: Colors.orange,
          child: Text("没有Positioned")
      ),
      Positioned(child: Text("底部居左"), left: 18, bottom: 18,),
    ],
  ),
);

运行效果:



我们发现设置fit: StackFit.loose后橘色区域与设置的宽高一致,我们看设置fit: StackFit.expand的效果:



说明fit属性为 StackFit.expand时,没有设置定位的子widget会占满stack。
passthrough官方文档说明的是将stack的父widget的布局大小约束无修改的传递给 Stack 的子Widget。试过之后发现与expand效果一致,也许还有其它区别尚未发现。
enum Clip {
    // 不裁剪
    none,
    // 裁剪,不抗锯齿
    hardEdge,
    // 裁剪,抗锯齿
    antiAlias,
    // 裁剪,抗锯齿
    antiAliasWithSaveLayer,
}

当clipBehavior属性为none时,超出部分不会被裁剪;为hardEdge,antiAlias,antiAliasWithSaveLayer时,超出部分会被裁剪。默认是hardEdge。
代码如下:

Container(
    width: 300,
    height: 300,
    color: Colors.blue,
    child: Stack(
      clipBehavior: Clip.none,
      children: const [
        Positioned(left: 250, bottom: 18,child: Text("我是一段很长很长很长很长很长很长很长很长的文字"),),
      ],
    ),
  );

运行效果:



属性为hardEdge,antiAlias,antiAliasWithSaveLayer时,运行效果:



Stack的直接子类有IndexedStack,其中有一个index属性,为可见子组件的index位置。这里就不细说了。
上一篇下一篇

猜你喜欢

热点阅读