首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >【Flutter 组件集录】Stack | 8 月更文挑战

【Flutter 组件集录】Stack | 8 月更文挑战

作者头像
张风捷特烈
发布2022-03-18 15:47:51
发布2022-03-18 15:47:51
6260
举报
1. 认识 Stack 组件

Stack 是一个经常被用到的组件,我看可以通过它来叠合若干个组件。源码中对它的介绍是:

代码语言:javascript
复制
一个将其子部件,相对于盒边缘进行定位的组件。

也就是说 Stack 组件擅长的是 定位 组件。下面是 Stack 组件类的定义构造方法,可以看出它继承自 MultiChildRenderObjectWidget。所以可接受一个组件列表。另外还有一些配置参数,在下面将一一介绍 。

2. Stack 组件的简单使用

如下,通过 Stack 将蓝色盒子、红色盒子和一个图标叠放在一起。可以看出,默认情况下组件会以 Stack 区域的左上角进行对齐叠放,且会根据列表元素的顺序依次叠放。

代码语言:javascript
复制
Stack(
  children: <Widget>[
    Container( width: 100, height: 100, color: Colors.red ),
    Container( width: 60, height: 60, color: Colors.green ),
    Icon(Icons.ac_unit,color: Colors.white )
  ],
);

textDirection属性

根据不同国家的阅读习惯,给出 textDirection 来确定排布方向。其类型为 TextDirection 枚举,有两个元素,rtl 代表从右向左,ltr 代表从左向右,我们的阅读习惯自然是 ltr

代码语言:javascript
复制
enum TextDirection {
  /// The text flows from right to left (e.g. Arabic, Hebrew).
  rtl,
  /// The text flows from left to right (e.g., English, French).
  ltr,
}

当把 textDirection 设为 rtl 时,效果如下,会以 Stack 区域的右上角进行对齐叠放。

代码语言:javascript
复制
Stack(
  textDirection: TextDirection.rtl,
  children: <Widget>[
    Container( width: 100, height: 100, color: Colors.red ),
    Container( width: 60, height: 60, color: Colors.green ),
    Icon(Icons.ac_unit,color: Colors.white )
  ],
);

alignment属性

alignment 属性我们应该非常熟悉,它的类型是 AlignmentGeometry ,用于控制对齐方式。比如将 alignment 设置为 Alignment.center 常量,就会在 Stack 中居中排布。

代码语言:javascript
复制
Stack(
  alignment: Alignment.center,
  children: <Widget>[
    Container( width: 100, height: 100, color: Colors.red ),
    Container( width: 60, height: 60, color: Colors.green ),
    Icon(Icons.ac_unit,color: Colors.white )
  ],
);

另外 Alignment 除了八个方位外,可以自己指定对齐方式。之前再 《出神入化的Align》 一文中详细介绍了 alignment 属性的用法,这里不再赘述。比如下面是 Alignment(0.2,0.2) 的效果。

3. Stack 的 fit 属性

fit 属性类型为 StackFit 枚举,有如下三个元素。默认情况下是 loose

代码语言:javascript
复制
enum StackFit {
  loose,
  expand,
  passthrough,
}

先看个例子:如下,在 Stack 外层通过 ConstrainedBox 施加一个宽高固定的约束,毫无疑问 Stack 在被强制约束后,其占位区域被固定。

代码语言:javascript
复制
ConstrainedBox(
  constraints: BoxConstraints.tightFor(width:200,height:150),
  child: Stack(
  fit: StackFit.loose,
  children: <Widget>[
    Container(width: 100, height: 100, color: Colors.red),
    Container(width: 60, height: 60, color: Colors.green),
    Icon(Icons.ac_unit,color: Colors.white,)
  ],
));

可以看出,在 StackFit.loose 的情况下,子组件并未受到该固定尺寸的约束,而是以该固定区域为上限的松散约束,如下红色所示。

此时,在 StackFit.expand 的情况下,子组件也会受到一个固定尺寸的强约束。

Container 在该约束下,会变成固定的宽高,即使蓝色自身要求是 60*60

其实稍微瞄一下 RenderStack 的源码我们就能知道 fit 具体的处理逻辑。在 loose 时,会通过 constraints.loosen() 将创建一个松散约束,该方法就是将最小宽高设为 0 ,最大宽高设为对应最大值。而 expand 会将自身约束的最大区域最为固定宽高约束。最后 passthrough 则什么都不处理,直接将自身约束施加给子节点。

代码语言:javascript
复制
BoxConstraints loosen() {
  assert(debugAssertIsValid());
  return BoxConstraints(
    minWidth: 0.0,
    maxWidth: maxWidth,
    minHeight: 0.0,
    maxHeight: maxHeight,
  );
4. Stack 的 overflow 与 clipBehavior 属性

我们可以清楚地看到 overflow 属性是一个过时的属性,而 clipBehavior 就是替代它的。clipBehavior 是什么我就不多说了,详见 ClipPath 一文。

那为什么需要 clipBehavior 进行裁剪呢?通过 Positioned 组件可以对子组件进行精确定位,甚至是负数。如下左边偏移 -20 ,右边偏移 -10 。默认裁剪行为是 hardEdge ,效果如下:

代码语言:javascript
复制
class StackDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return
      Container(
        color: Colors.grey.withAlpha(33),
        constraints: BoxConstraints.tightFor(width:200,height:150),
        child: Stack(
        children: <Widget>[
          Container(width: 100, height: 100, color: Colors.red),
          Positioned(
              left: -20,
              top: -10,
              child: Container(width: 60, height: 60, color: Colors.green)),
          Icon(Icons.ac_unit,color: Colors.white,)
        ],
      ));
  }
}

clipBehavior: Clip.none, 时,不会进行裁剪,出界的就会被显示出来。注意一点,出界的部分是无法响应点击事件的。如果需要点击,有其他组件能够解决。

Stack 的使用方式到这里就介绍完毕,那本文到这里就结束了,谢谢观看,明天见~

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021/08/23 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 认识 Stack 组件
  • 2. Stack 组件的简单使用
  • 3. Stack 的 fit 属性
  • 4. Stack 的 overflow 与 clipBehavior 属性
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档