为一篇 HarmonyOS 7 教程绘制手绘笔记风框架示意图,主题是“Blank() 为什么是 Ro

前言

刚开始写布局时,很多人处理间距的方法都差不多:margin 一路加,加到看起来差不多为止。

这种方式短期能解决问题,但一旦页面宽度变了、内容长度变了,布局就很容易开始别扭。真正更稳定的做法,往往不是继续堆固定值,而是把“剩余空间”交给布局系统自己处理。

这也是 Blank() 的价值。它看起来像个不起眼的小组件,但在 Row 里非常好用。

这份案例在演示什么

页面围绕 Blank() 展示了 4 类常见用法:

  • 左右撑开
  • 多个元素均匀分散

为教程中的代码案例绘制一张手绘信息图,展示 HarmonyOS 7 的 Blank() 在 Row

  • 导航栏居中布局
  • 和固定 margin 的对比

这些场景非常贴近日常业务页面。

完整代码

/**
 * BlankSpacerBasics - Blank 空白填充
 * 演示 Blank 组件在 Row 中用于创建间距
 */
import { PRESET_COLORS, generateListItems, PAGE_BG_COLOR, PANEL_BG_COLOR, ACCENT_COLOR, MUTED_TEXT_COLOR } from './types'

@Entry
@Component
struct BlankSpacerBasics {
  @State isShow: boolean = true

  build() {
    Column() {
      if (this.isShow) {
        Scroll() {
          Column({ space: 16 }) {
            Text('Blank 空白填充').fontSize(16).fontColor(ACCENT_COLOR).fontWeight(FontWeight.Bold)

            Column() {
              Text('基本用法: 左右撑开').fontSize(13).fontColor('#4D96FF').margin({ bottom: 8 })
              Row() {
                Text('左侧').fontSize(13).padding(10).backgroundColor('#4D96FF').fontColor('#FFFFFF').borderRadius(6)
                Blank()
                Text('右侧').fontSize(13).padding(10).backgroundColor('#FFA500').fontColor('#FFFFFF').borderRadius(6)
              }.width('100%')
            }
            .backgroundColor(PANEL_BG_COLOR).padding(12).borderRadius(12)

            Column() {
              Text('均匀分散布局').fontSize(13).fontColor('#6BCB77').margin({ bottom: 8 })
              Row() {
                Text('A').fontSize(13).padding(10).backgroundColor('#6BCB77').fontColor('#FFFFFF').borderRadius(6)
                Blank()
                Text('B').fontSize(13).padding(10).backgroundColor('#4ECDC4').fontColor('#FFFFFF').borderRadius(6)
                Blank()
                Text('C').fontSize(13).padding(10).backgroundColor('#FFD93D').fontColor('#FFFFFF').borderRadius(6)
              }.width('100%')
            }
            .backgroundColor('#F0FAF1').padding(12).borderRadius(12)

            Column() {
              Text('导航栏布局').fontSize(13).fontColor('#9B59B6').margin({ bottom: 8 })
              Row() {
                Text('←').fontSize(16).fontColor('#FFFFFF')
                  .width(36).height(36).backgroundColor('#9B59B6').borderRadius(18).textAlign(TextAlign.Center)
                Blank()
                Text('页面标题').fontSize(16).fontColor('#1A1A1A').fontWeight(FontWeight.Bold)
                Blank()
                Text('...').fontSize(16).fontColor('#FFFFFF')
                  .width(36).height(36).backgroundColor('#9B59B6').borderRadius(18).textAlign(TextAlign.Center)
              }.width('100%')
            }
            .backgroundColor('#F5EEF8').padding(12).borderRadius(12)

            Column() {
              Text('Blank vs 固定 Margin').fontSize(13).fontColor('#FFA500').margin({ bottom: 8 })
              Row() {
                Text('margin固定间距').fontSize(10).fontColor('#FFA500')
                Text('元素1').padding(6).backgroundColor('#FFD93D').borderRadius(4).fontSize(10).margin({ left: 8 })
                Text('元素2').padding(6).backgroundColor('#FFD93D').borderRadius(4).fontSize(10).margin({ left: 8 })
              }.margin({ bottom: 6 })
              Row() {
                Text('Blank弹性间距').fontSize(10).fontColor('#4D96FF')
                Text('元素1').padding(6).backgroundColor('#4D96FF').borderRadius(4).fontColor('#FFFFFF').fontSize(10)
                Blank()
                Text('元素2').padding(6).backgroundColor('#4D96FF').borderRadius(4).fontColor('#FFFFFF').fontSize(10)
              }.width('100%')
            }
            .backgroundColor('#FFF8E8').padding(12).borderRadius(12)
          }.width('100%')
        }
      }
      Text('Blank 弹性间距 - 用剩余空间组织 Row 的秩序')
        .fontSize(12).fontColor(MUTED_TEXT_COLOR).margin({ top: 12 })
    }
    .width('100%').height('100%').backgroundColor(PAGE_BG_COLOR).padding(16)
  }
}

为文章中的“Blank vs 固定 Margin”部分绘制一张对比图,采用 sketch-notes

Blank() 到底在做什么

一句话解释就是:

它不显示内容,但会主动吃掉当前布局里剩余的可用空间。

这件事在 Row 里特别好用。因为横向布局里,经常会有“左边一个东西,右边一个东西,中间自动拉开”的需求。

最基础的左右撑开,为什么这么常见

第一块结构很典型:

Row() {
  Text('左侧')
  Blank()
  Text('右侧')
}

这就是最常见的“左右两端对齐”写法。

它适合:

  • 标题 + 操作按钮
  • 标签 + 数值
  • 左文案 + 右状态
  • 表单项名 + 右侧说明

你会发现,很多业务行布局其实都能直接套这个思路。

多个 Blank() 为什么能均分空间

案例第二块用了两个 Blank()

Text('A')
Blank()
Text('B')
Blank()
Text('C')

这意味着剩余空间会被两个空白块一起分掉,于是三个元素就会更自然地拉开。

这类结构很适合:

  • 顶部筛选项
  • 工具栏分区
  • 多个轻量按钮的均匀分散布局

导航栏为什么特别适合用 Blank()

第三块非常贴近实际业务:

左按钮
Blank()
标题
Blank()
右按钮

这类写法最大的好处是,不需要你手动算标题该偏移多少。左右空白会自动帮你把中心区域撑住,让标题更容易保持视觉居中。

对移动端导航栏来说,这是非常实用的思路。

为什么要把 Blank() 和固定 margin 放在一起对比

这部分其实是整篇最有教学价值的地方。

固定 margin 的特点是:

  • 简单
  • 直接
  • 适合确定性的局部间距

但它的问题也很明显:

  • 容器宽度变化时不够灵活
  • 内容长度变化时容易挤
  • 想两端拉开时会越写越别扭

Blank() 的思路是让剩余空间自己去适配,所以它更适合做结构性间距,而不是细碎微调。

关键代码单独讲解

Blank()

核心组件本体,不显示内容,但参与布局分配。

.width('100%')

很多 Row 都配了整行宽度,这样 Blank() 才有足够的剩余空间可分配。

Text('页面标题') 两侧各放一个 Blank()

这是很经典的导航栏居中技巧,尤其适合左右都有操作按钮的场景。

小白最容易踩的坑

1. 把 Blank() 当成普通占位块

它真正的价值不是占位,而是吃掉剩余空间。

2. 容器本身没宽度,结果 Blank() 看起来没效果

如果 Row 没有可分配的剩余空间,Blank() 自然也发挥不出来。

3. 所有间距都想靠 Blank() 解决

它适合结构性拉伸,不适合所有细节间距微调。

这份代码能怎么改成真实业务

场景 改法
设置页条目 左标签右开关,中间用 Blank() 拉开
顶部导航栏 左返回、居中标题、右操作按钮
数据概览行 左指标名,右统计值
工具栏 多个区域用 Blank() 分段排列

动手改一改

  • 把导航栏右侧按钮换成两个图标,看标题还能否保持稳定居中。
  • 在一行里放四个元素,尝试用多个 Blank() 重新组织布局。
  • 对比 marginBlank() 在窄屏下的表现差异。
  • 把其中一块改成真实业务行,比如“用户名 + 等级 + 操作”。

写在最后

Blank() 这种组件,名字听起来很普通,但在布局里特别有价值。它最大的优点不是炫,而是稳。你不用一直猜间距该写多少,很多横向排布问题它都能帮你自然化解。

如果你刚开始做 HarmonyOS7 的页面布局,我非常建议把这篇亲手练熟。等你开始习惯用剩余空间来组织界面,而不是一味堆固定间距,布局质量会明显上一个台阶。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐