在这里插入图片描述
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

案例概述

本案例展示如何使用 LayoutBuilder 根据父容器的实际尺寸动态决定布局结构,例如:自动计算网格的列数,从而在不同宽度下合理排布内容区块。

核心概念

  • LayoutBuilder 提供当前布局约束(BoxConstraints),可以获取可用宽度;
  • 根据 constraints.maxWidth 动态计算列数;
  • 搭配 GridView.count 构建响应式网格。

代码片段与说明

1. 使用 LayoutBuilder 获取可用宽度

body: LayoutBuilder(
  builder: (context, constraints) {
    final maxWidth = constraints.maxWidth;
    int columnCount;
    if (maxWidth < 400) {
      columnCount = 1;
    } else if (maxWidth < 800) {
      columnCount = 2;
    } else {
      columnCount = 3;
    }
    // ... 返回具体布局
  },
),

说明:

  • constraints.maxWidth 是当前区域的最大可用宽度,不一定等于整个屏幕宽度;
  • 根据不同宽度区间映射到不同列数,是响应式布局的一个常见写法。

2. 构建响应式网格

Expanded(
  child: GridView.count(
    crossAxisCount: columnCount,
    crossAxisSpacing: 12,
    mainAxisSpacing: 12,
    children: List.generate(9, (index) {
      return Container(
        decoration: BoxDecoration(
          color: Colors.blue.shade100,
          borderRadius: BorderRadius.circular(8),
        ),
        child: Center(child: Text('区块 ${index + 1}')),
      );
    }),
  ),
),

说明:

  • 列数由 columnCount 决定,随父容器宽度变化;
  • 区块数量固定为 9 个,只是布局方式在窄屏和宽屏之间不同;
  • 适合用于仪表盘、小组件面板等场景。

应用场景

  • PC 端宽屏仪表盘,根据窗口宽度自动调整每行显示的卡片数量;
  • 平板端分栏表单布局,根据横竖屏不同动态变更列数;
  • 容器内嵌场景(例如在抽屉或弹窗中),使用父容器宽度而不是整屏宽度来做适配。

深入理解:LayoutBuilder 的设计哲学

1. LayoutBuilder vs MediaQuery:何时使用哪一个?

  • MediaQuery:获取整个屏幕/窗口的尺寸,适合做全局的设备判断;
  • LayoutBuilder:获取当前组件的父容器尺寸,适合做局部的响应式调整。

两者的关键区别在于:

  • 如果你的组件是页面的根组件,两者获取的尺寸基本相同;
  • 如果你的组件被嵌入在其他容器中(如抽屉、弹窗、侧边栏),LayoutBuilder 获取的是父容器尺寸,而 MediaQuery 获取的仍是整屏尺寸。

因此,LayoutBuilder 更适合构建可复用的、自适应的组件,因为它不依赖全局屏幕尺寸,而是根据自己的父容器来调整。

2. 动态布局的优势

使用 LayoutBuilder 动态计算列数,相比硬编码的好处有:

  • 自动适应:无需手动维护多套断点,组件会自动根据可用宽度调整;
  • 可复用性强:同一个组件可以在不同的父容器中使用,都能自动适应;
  • 减少代码重复:不需要在多个地方重复写设备判断逻辑。

3. 网格列数的计算策略

在本案例中,我们使用了简单的分段策略:

< 400px → 1 列
400–800px → 2 列
>= 800px → 3 列

但在实际项目中,你可能需要更精细的策略:

  • 基于卡片宽度:定义每个卡片的最小宽度(如 200px),然后计算 列数 = 可用宽度 / 最小卡片宽度
  • 基于屏幕密度:在高分辨率屏幕上显示更多列;
  • 基于内容:不同类型的内容可能需要不同的列数。

4. LayoutBuilder 的性能考量

LayoutBuilder 会在父容器尺寸变化时重新调用 builder 函数,这可能导致频繁的重建。优化策略包括:

  • 缓存计算结果:如果列数计算比较复杂,可以用 constfinal 缓存中间结果;
  • 避免在 builder 中创建复杂对象:尽量在 builder 外部创建,然后传入;
  • 使用 RepaintBoundary:如果 builder 内部有复杂的绘制,可以用 RepaintBoundary 优化重绘。

5. LayoutBuilder 在业务系统中的应用

  • 仪表盘:根据窗口宽度动态调整卡片网格的列数;
  • 表单布局:根据可用宽度决定表单字段是单列还是多列排列;
  • 响应式表格:根据容器宽度动态隐藏或显示表格列;
  • 自适应列表:在不同宽度的容器中都能保持良好的布局。

通过掌握 LayoutBuilder,你可以构建出真正响应式的、可复用的 UI 组件。

Logo

社区规范:仅讨论OpenHarmony相关问题。

更多推荐