Flutter-详解布局(弹性和层叠布局辅助控件)

DEMO

弹性布局辅助控件

1. Expanded

  • 说明: 作为Row、Column或Flex的子Widget,可以扩展以填充主轴上的可用空间

  • 规则: 必须位于Row、Column或Flex内。flex参数用于分配剩余空间的比例(默认为1)

  • 注意: 在Row或Column中,如果子Widget的总主轴长度超过可用空间,使用Expanded可以避免溢出,因为它会压缩子Widget(强制子Widget适应分配的空间)

  • 推荐: 在需要子Widget按比例分配空间时使用,比例分割布局(如 70%-30% 面板)

Row(
  children: [
    Expanded(flex: 2, child: Container(color: Colors.red)), // 占2/3空间
    Expanded(flex: 1, child: Container(color: Colors.green)), // 占1/3空间
  ],
)
Expanded

2. Flexible

  • 说明: 与Expanded类似,但更灵活。Expanded是Flexible(fit: FlexFit.tight)的简写。Flexible的默认fit是FlexFit.loose,即子Widget不需要填满分配的空间

  • 规则: 同样必须位于Row、Column或Flex内

  • 注意: Flexible与Expanded的区别:Expanded会强制子Widget填满空间,而Flexible则允许子Widget使用更小的空间

  • 推荐: 当需要子Widget有弹性但不需要强制填满时使用,自适应表格列

Row(
    children: [
      Flexible(
        child: Container(height: 50, color: Colors.red),
      ),
      
      Flexible(
        child: Container(
            height: 100,
            color: Colors
                .green), // 这个容器高度100,但Row高度由最高子Widget决定(100),红色容器高度50,但会被拉伸到100(因为Row交叉轴是垂直方向,默认是stretch)
      ),
    ],
)

注意:Row的交叉轴对齐默认是stretch,所以子Widget在垂直方向会被拉伸。如果不想被拉伸,可以设置crossAxisAlignment: CrossAxisAlignment.start。

Flexible

3. Spacer

  • 说明: 在弹性布局中占据剩余空间(相当于Expanded包裹一个空的SizedBox),是一个用于在 Row、Column 或 Flex 布局中填充剩余空间的空白组件

  • 规则: 它会根据 flex 参数按比例占据主轴(水平或垂直方向)的可用空间,类似弹性布局中的“弹簧”,flex(默认值为1):指定空间分配比例。例如,两个 Spacer(flex: 2) 和 Spacer(flex: 1) 会按 2:1 分配剩余空间

  • 注意: 必须作为 Row、Column 或 Flex 的直接子组件,空间不足时可能引发溢出错误(需确保父容器有足够空间)

  • 推荐: 等间距按钮组,左右对齐元素,多比例空间分配

Column(
  children: [
    const Text(
      "顶部标题",
      style: TextStyle(
        color: Colors.blue,
      ),
    ),
    const Spacer(flex: 1),
    const Row(
      children: [
        Text(
          "左侧文本",
          style: TextStyle(
            color: Colors.black,
          ),
        ),
        Spacer(flex: 2),
        Text("中间文本",
            style: TextStyle(
              color: Colors.red,
            )),
        Spacer(flex: 1),
        Icon(Icons.star),
      ],
    ),
    const Spacer(flex: 3), // 下方大面积留白
    ElevatedButton(
      onPressed: () {},
      child: const Text(
        "确认",
        style: TextStyle(
          color: Colors.blue,
        ),
      ),
    ),
  ],
)
Spacer

层叠布局辅助控件

1. Positioned

  • 说明: 仅作为 Stack 的直接子组件使用,用于在层叠布局中精确定位子组件,类似 CSS 的绝对定位

  • 规则: left、right、top、bottom(控制子组件相对于父 Stack 边缘的距离),width、height(可选,用于固定子组件尺寸),支持 Positioned(topLeft/bottomRight) 等快捷方式

  • 注意: 若设置 left + right,则不能同时设置 width;同理适用于 top + bottom 与 height 的冲突,未设置尺寸时,需至少指定两个相对定位属性(如 left 和 right)以确定布局范围

  • 推荐: 结合 MediaQuery 动态计算定位值,适配不同屏幕尺寸,使用 Align 简化对齐逻辑

Stack(
  fit: StackFit.expand, // 填充父容器
  children: [
    Positioned(
      left: 10,
      right: 10,
      height: 80,
      child: Container(color: Colors.orange), // 水平居中且宽度自适应
    ),
    Positioned(
      top: 10,
      bottom: 10,
      width: 80,
      child: Container(color: Colors.purple), // 垂直居中且高度自适应
    ),
  ],
)
Positioned

2. PositionedDirectional

  • 说明: 它用于在 Stack 中根据 textDirection 的方向来定位子部件。与 Positioned 不同,PositionedDirectional 接受的是一个偏移量和一个 textDirection 参数,从而决定子部件相对 Stack 的位置。这使得在布局中使用 PositionedDirectional 更加灵活和方便

  • 规则: start:在 TextDirection.ltr (从左到右)时对应 left,在 TextDirection.rtl (从右到左)时对应 right。end:在 TextDirection.ltr 时对应 right,在 TextDirection.rtl 时对应 left。top 和 bottom 保持固定方向,不受文本方向影响

  • 注意: 必须作为 Stack 的直接子组件,否则会抛出错误,支持 width 和 height 属性,但需注意与 start/end 和 top/bottom 的组合规则

  • 推荐: 可通过 AnimatedPositionedDirectional 实现位置变化的动画效果,适配不同语言方向的布局(如阿拉伯语、希伯来语)

Directionality(
  // 设置文本方向(ltr 或 rtl)
  textDirection: TextDirection.rtl,
  child: Stack(
    children: [
      PositionedDirectional(
        start: 20.0, // 在 rtl 环境下对应 right=20
        top: 50.0,
        child: Container(
          width: 100,
          height: 100,
          color: Colors.blue,
          child: const Center(child: Text('动态定位')),
        ),
      ),
      // 其他子组件...
    ],
  ),
)
PositionedDirectional

因为网站字数限制,只能分系列了,需要一次性看完请去这里
Flutter-详解布局(核心布局控件)
Flutter-详解布局(单子组件布局控件)
Flutter-详解布局(滚动和Sliver系列布局控件)
Flutter-详解布局(响应式和平台适配及特殊布局控件)
需要代码去这里DEMO

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。