用 ArkUI 打造媲美小红书的瀑布流布局,原来只需一个 Grid!

摘要

在当今移动端开发中,瀑布流布局已经成为图像展示、商品推荐、内容流推送等界面设计的"标配"。它能实现错落有致、不规则高宽度的排布形式,既美观又高效。而在 HarmonyOS 的 ArkUI 框架中,虽然没有直接命名为"瀑布流"的组件,但我们可以巧妙地使用 Grid 组件加上不定高的 item 来灵活实现这一布局。本文将从 ArkUI 的组件原理出发,带你搭建一个完整的瀑布流布局页面,覆盖实战 Demo、多个场景案例、动态列数适配、性能优化技巧等内容,帮助你快速掌握并落地这一常见界面需求。

引言:瀑布流为什么受欢迎?

如果你刷过小红书、看过 Pinterest、逛过淘宝推荐页,就一定见过瀑布流。它的最大特点是每个 item 高度不同,但能自动依列往下补位,形成流动性很强的错落排布效果

相比传统的网格布局(Grid Layout)或线性列表(ListView),瀑布流具备:

  • 视觉流动感强:非规则的高度组合形成自然流动效果;
  • 空间利用率高:不会因为固定行高而造成空白;
  • 适应图文信息流:特别适合封面图+标题、短视频卡片、商品瀑布推荐等。

ArkUI 中的 Grid:不是瀑布流,但可以变成瀑布流

基础结构:Grid 是如何工作的?

ArkUI 的 Grid 组件是一个典型的二维网格结构,你可以为其指定列数 columns,每行会自动塞满元素,每个 itemBuilder 构建的组件会根据其内容自动调整大小。

ts 复制代码
Grid({
  columns: 2,
  data: this.items,
  itemBuilder: (item) => {
    return Box().width('90%').height(150).backgroundColor(item);
  }
})

重点在于:只要你每个 item 的高度不同,Grid 就会呈现瀑布效果

ArkUI 不像 CSS 有 Masonry 怎么办?

确实,ArkUI 没有 masonryflex-wrapposition: absolute 等 CSS 手段,但它提供了类似的"列优先"渲染逻辑,你可以通过:

  • 手动设置 item 不同高度;
  • 控制列数来影响排布密度;
  • 利用 FlexColumn 组合组件构造多样内容;

从而达到同样视觉效果。

从零开始构建瀑布流布局

Demo:构造一个彩色瀑布格子页

ts 复制代码
@Entry
@Component
struct WaterfallFlowExample {
  private items: string[] = Array.from({ length: 30 }, (_, i) => `#${Math.floor(Math.random() * 0xffffff).toString(16)}`);

  build() {
    Column() {
      Text('ArkUI 瀑布流示例')
        .fontSize(22)
        .fontWeight(FontWeight.Bold)
        .margin({ top: 20, bottom: 10 })
        .align(Alignment.Center);

      Grid({
        columns: 2,
        data: this.items,
        itemBuilder: (item) => {
          let height = 100 + Math.floor(Math.random() * 100); // 随机高度
          return Box()
            .width('90%')
            .height(height)
            .backgroundColor(item)
            .borderRadius(12)
            .margin(10)
            .align(Alignment.Center);
        }
      }).width('100%');
    }
  }
}

代码说明

组件 作用
Grid(columns: 2) 设置两列排布
itemBuilder 动态渲染每个 item,传入的 item 为颜色值
height = 100 + 随机 随机高度形成不规则视觉
Box() 内容容器,设置背景色和大小

提示: 这里的随机高度模拟的是实际场景中,比如商品卡片图片、视频封面、图文摘要块内容高度不同的情况。

实际场景应用案例

电商类:商品卡片流展示

瀑布流最常见的应用之一就是商品推荐,比如淘宝首页、京东发现频道。每个商品高度不同(因图片或描述),用瀑布流可以最大程度利用屏幕空间。

示例代码

ts 复制代码
let productList = [
  { name: 'T恤', price: '¥59', color: '#ffe4e1', height: 180 },
  { name: '牛仔裤', price: '¥128', color: '#e0ffff', height: 220 },
  { name: '运动鞋', price: '¥289', color: '#f0e68c', height: 160 },
  // ...可扩展更多商品
];

Grid({
  columns: 2,
  data: productList,
  itemBuilder: (item) => {
    return Column()
      .width('90%')
      .height(item.height)
      .backgroundColor(item.color)
      .borderRadius(12)
      .padding(10)
      .margin(8)
      .justifyContent(FlexAlign.SpaceBetween)
      .align(Alignment.Center)
      .children([
        Text(item.name).fontSize(16).fontWeight(FontWeight.Medium),
        Text(item.price).fontSize(14).fontColor(Color.Red)
      ]);
  }
}).width('100%');

图文信息流 / 社交推荐流

你也可以封装内容卡片组件,用于推荐文章、小视频、短图文等。如下为封装示例:

ts 复制代码
@Component
struct ContentCard {
  @Prop item: { title: string; desc: string; color: string; height: number };

  build() {
    Column()
      .width('90%')
      .height(this.item.height)
      .backgroundColor(this.item.color)
      .padding(10)
      .borderRadius(10)
      .children([
        Text(this.item.title).fontSize(18).fontWeight(FontWeight.Bold),
        Text(this.item.desc).fontSize(14).margin({ top: 6 })
      ]);
  }
}

然后在主布局中:

ts 复制代码
Grid({
  columns: 2,
  data: articleList,
  itemBuilder: (item) => {
    return ContentCard({ item });
  }
});

实战技巧进阶篇

动态列数适配设备宽度

通过屏幕宽度判断列数,实现响应式布局:

ts 复制代码
let deviceWidth = device.screenWidth;
let columns = deviceWidth > 800 ? 3 : 2;

Grid({
  columns: columns,
  data: this.items,
  itemBuilder: ...
});

Scroll 配合懒加载(分页)

ArkUI 的 Scroll 可以配合加载更多按钮或滑动到底触发加载:

ts 复制代码
Scroll() {
  Grid({
    columns: 2,
    data: this.items,
    itemBuilder: ...
  });

  Button("加载更多")
    .onClick(() => this.loadMore());
}

开发者常见问题解答

Q1:ArkUI 为什么不提供内置瀑布流组件?

ArkUI 是一个偏低层的 UI 框架,它提供的是通用的布局组件,而不是封装复杂行为的高阶组件。这样反而更灵活,我们可以自由控制样式、行为和性能。

Q2:Grid 布局时 item 不对齐怎么办?

确保你:

  • 设置了统一 Box().width('90%')
  • 控制好 margin
  • 外层容器 .width('100%')

这样每列对齐不会错位。

Q3:每个 item 高度不一会不会影响性能?

不会太大影响,ArkUI 的渲染逻辑是分块计算的。只要你 item 数量不过多(<1000),或结合分页处理,性能基本没有问题。

总结:借力 Grid,ArkUI 也能"瀑"得漂亮!

本文通过多个维度深入讲解了 ArkUI 中如何实现瀑布流布局。虽然没有现成组件,但借助 Grid 与自定义 item 高度,我们完全可以打造出高性能、易扩展的瀑布流效果。你可以自由调整列数、高度、内容结构,配合封装的组件、分页加载等逻辑,实现适用于图文、电商、社交等多种 App 场景的通用 UI 模板。

重点回顾:

  • 利用 Grid(columns: n) 设置列数;
  • 每个 itemBuilder 设置不同高度,即可模拟瀑布流;
  • 结合 Scroll、分页、动态列数可做成完整内容流;
  • 场景涵盖商品展示、文章推荐、图文封面流等;

未来你也可以将这套布局封装为自定义组件,作为团队项目的 UI 模板进行复用,提高开发效率。

相关推荐
zhanshuo11 小时前
在鸿蒙里优雅地处理网络错误:从 Demo 到实战案例
harmonyos
zhanshuo11 小时前
在鸿蒙中实现深色/浅色模式切换:从原理到可运行 Demo
harmonyos
whysqwhw16 小时前
鸿蒙分布式投屏
harmonyos
whysqwhw17 小时前
鸿蒙AVSession Kit
harmonyos
whysqwhw19 小时前
鸿蒙各种生命周期
harmonyos
whysqwhw20 小时前
鸿蒙音频编码
harmonyos
whysqwhw20 小时前
鸿蒙音频解码
harmonyos
whysqwhw20 小时前
鸿蒙视频解码
harmonyos
whysqwhw20 小时前
鸿蒙视频编码
harmonyos
ajassi200020 小时前
开源 Arkts 鸿蒙应用 开发(十八)通讯--Ble低功耗蓝牙服务器
华为·开源·harmonyos