鸿蒙UI开发核心:ArkUI布局组件详解(二) 原创
头像 ●VON 2025-11-22 18:15:26    发布
4827 浏览 141 点赞 0 收藏

前言

在掌握了 ColumnRowStack 这三大基础布局后,我们已经能够构建静态页面结构。然而,真实应用中大量内容是动态的、可滚动的、数量不确定的——比如商品列表、新闻资讯、相册图集等。这时,就需要 ArkUI 提供的高级布局容器:List(列表布局)、Grid(网格布局)和 Scroll(滚动布局)

本文将深入讲解这三类组件的核心用法,重点聚焦于 数据驱动渲染、item 布局定制、事件响应处理,并通过“商品列表”和“图片画廊”两个典型场景,带你掌握鸿蒙应用中高频出现的动态 UI 实现方式。



一、List:高性能列表布局

List 是用于展示纵向或横向滚动列表的容器,专为大量数据项优化,支持懒加载、复用机制,性能远优于手动用 Column + Scroll 拼接。

1. 基本语法与数据绑定

@Entry
@Component
struct ProductListPage {
  // 模拟商品数据
  private products: Array<{ id: number; name: string; price: number }> = [
    { id: 1, name: '无线耳机', price: 299 },
    { id: 2, name: '智能手表', price: 1299 },
    { id: 3, name: '平板电脑', price: 2499 },
    // ...更多数据
  ];

  build() {
    List({ space: 12 }) {
      ForEach(this.products, (item) => {
        ListItem() {
          this.ProductItem(item);
        }
      }, item => item.id.toString()) // key 值,提升渲染性能
    }
    .width('100%')
    .height('100%')
    .padding(16)
  }

  @Builder
  ProductItem(item: { id: number; name: string; price: number }) {
    Row() {
      Image($r('app.media.product_default'))
        .width(80)
        .height(80)
        .borderRadius(8)

      Column() {
        Text(item.name)
          .fontSize(16)
          .fontWeight(FontWeight.Medium)
        Text(`¥${item.price}`)
          .fontSize(14)
          .fontColor('#e54d42')
          .margin({ top: 4 })
      }
      .layoutWeight(1)
      .alignItems(HorizontalAlign.Start)
    }
    .width('100%')
    .padding(12)
    .backgroundColor('#fff')
    .borderRadius(10)
    .onClick(() => {
      console.log(`点击了商品:${item.name}`);
      // 可跳转详情页
    })
  }
}

2. 关键特性说明

  • ForEach:用于遍历数据源,必须提供唯一 key(如 item.id),确保高效更新;
  • ListItem():List 的子项容器,不可省略;
  • @Builder:将 item UI 封装为可复用构建器,提升代码可读性;
  • 事件处理:直接在 ListItem 或内部组件上绑定 .onClick()
✅ 适用场景:消息列表、订单记录、设置菜单、新闻流等。


二、Grid:灵活网格布局

Grid 用于展示二维网格结构,常用于相册、商品橱窗、图标面板等场景。支持行列数动态配置、间距控制、滚动方向设置。

1. 基本用法:图片画廊

@Entry
@Component
struct PhotoGallery {
  private images: string[] = [
    $r('app.media.photo1'),
    $r('app.media.photo2'),
    $r('app.media.photo3'),
    // ...共12张
  ];

  build() {
    Grid() {
      ForEach(this.images, (imgSrc, index) => {
        GridItem() {
          Image(imgSrc)
            .objectFit(ImageFit.Cover) // 图片填充模式
            .width('100%')
            .height('100%')
        }
        .aspectRatio(1) // 保持 1:1 宽高比
      }, item => index.toString())
    }
    .columnsTemplate('1fr 1fr 1fr') // 三列等宽
    .rowsTemplate('repeat(auto-fill, 120px)') // 行高固定120px
    .columnsGap(8)
    .rowsGap(8)
    .width('100%')
    .height('100%')
    .padding(8)
  }
}

2. 核心属性解析

属性说明
columnsTemplate列模板,如 '1fr 1fr' 表示两列等宽
rowsTemplate行模板,常用 repeat(auto-fill, 100px) 自动换行
columnsGap / rowsGap列间距与行间距
GridItem().aspectRatio(ratio)设置子项宽高比(如 1 表示正方形)
💡 技巧:使用 aspectRatio(1) 可轻松实现“正方形图片网格”,避免图片拉伸。
✅ 适用场景:相册、商品橱窗、应用图标桌面、标签云等。


三、Scroll:通用滚动容器

当内容超出屏幕范围时,Scroll 提供基础滚动能力。虽然 ListGrid 自带滚动,但 Scroll 更适合包裹混合布局(如图文混排长页面)。

示例:长文章详情页

Scroll() {
  Column() {
    Image($r('app.media.article_banner'))
      .width('100%')
      .height(200)
      .objectFit(ImageFit.Fill)

    Text('鸿蒙生态的未来展望')
      .fontSize(24)
      .fontWeight(FontWeight.Bold)
      .margin({ top: 16, horizontal: 16 })

    Text('HarmonyOS 自发布以来...')
      .fontSize(16)
      .lineHeight(28)
      .margin({ top: 12, horizontal: 16 })
      .textAlign(TextAlign.Justify)

    // 可继续添加评论区、推荐文章等模块
  }
}
.width('100%')
.height('100%')
.scrollable(ScrollDirection.Vertical) // 默认垂直滚动

注意事项

  • Scroll 内部通常只有一个直接子组件(如 Column);
  • 不适用于大量重复 item(此时应优先用 List);
  • 支持 .onScroll(event => {...}) 监听滚动位置,实现吸顶、懒加载等效果。


四、综合实战:电商首页商品区

现在,我们将结合 ListGrid,模拟一个电商 App 的首页片段:

Column() {
  // 轮播图(此处简化)
  Text('【Banner 轮播图】')
    .width('100%')
    .height(160)
    .backgroundColor('#eee')
    .textAlign(TextAlign.Center)

  // 分类导航(Row)
  Row() {
    ForEach(['手机', '电脑', '穿戴', '家居'], (category) => {
      Text(category)
        .width(80)
        .height(40)
        .backgroundColor('#f0f0f0')
        .textAlign(TextAlign.Center)
        .borderRadius(20)
    })
  }
  .space(12)
  .padding({ horizontal: 16, top: 12 })

  // 商品网格(热销推荐)
  Text('🔥 热销推荐')
    .fontSize(18)
    .fontWeight(FontWeight.Bold)
    .margin({ top: 16, left: 16 })

  Grid() {
    ForEach(this.hotProducts, (item) => {
      GridItem() {
        Column() {
          Image($r('app.media.product_default'))
            .width('100%')
            .aspectRatio(1)
            .borderRadius(8)
          Text(item.name)
            .fontSize(14)
            .maxLines(1)
            .textOverflow({ overflow: TextOverflow.Ellipsis })
          Text(`¥${item.price}`)
            .fontSize(14)
            .fontColor('#e54d42')
            .margin({ top: 4 })
        }
        .width('100%')
        .padding(6)
        .backgroundColor('#fff')
        .borderRadius(8)
        .onClick(() => {
          router.pushUrl({ url: `pages/ProductDetail?id=${item.id}` });
        })
      }
    }, item => item.id.toString())
  }
  .columnsTemplate('1fr 1fr 1fr 1fr') // 四列
  .columnsGap(8)
  .rowsGap(12)
  .padding({ horizontal: 8, bottom: 16 })
}
.height('100%')
.backgroundColor('#f8f8f8')
🔍 设计亮点: 使用 Grid 实现四列商品网格,适配手机屏幕; 每个商品项包含图片、标题、价格,点击跳转详情; 整体嵌套在 Column 中,与其他模块(Banner、分类)组合成完整页面。


五、性能与最佳实践

⚠️ 避免常见陷阱

  • 不要在 ForEach 中直接写复杂逻辑,应提取为 @Builder
  • 确保 key 唯一且稳定,避免使用数组索引(index)作为 key;
  • 图片务必设置尺寸和 objectFit,防止布局抖动。

✅ 推荐做法

  • 大量数据用 List,网格展示用 Grid,混合长内容用 Scroll
  • 结合 LazyForEach(进阶)实现超大数据集的按需加载;
  • 使用 cachedCount 预加载相邻 item,提升滚动流畅度。


六、小结

今天我们系统学习了 ArkUI 的三大动态布局组件:

  • List:高效渲染纵向/横向列表,适合消息流、商品列表;
  • Grid:灵活构建二维网格,适用于相册、图标面板;
  • Scroll:通用滚动容器,用于混合内容长页面。

通过数据绑定、事件处理与布局组合,你已经具备实现主流 App 页面的能力。下一步,我们将深入 状态管理与组件通信,让你的 UI 不仅“看得见”,更能“动起来”!

🛠️ 动手练习建议: 用 List 实现一个“待办事项”列表,支持点击完成/删除; 用 Grid 构建一个“应用图标桌面”,长按可编辑; 在 Scroll 中实现一个“个人主页”,包含头像、简介、动态、关注列表等模块。
©本站发布的所有内容,包括但不限于文字、图片、音频、视频、图表、标志、标识、广告、商标、商号、域名、软件、程序等,除特别标明外,均来源于网络或用户投稿,版权归原作者或原出处所有。我们致力于保护原作者版权,若涉及版权问题,请及时联系我们进行处理。
分类
OpenHarmony

暂无评论数据

发布

头像

●VON

HarmonyOS应用开发者初级工程师、影刀初级RPA工程师、YashanDB数据库V23.2认证管理员、金仓数据库认证专员等技能证书,主持参与省级团队赛9项,个人赛2项均获得省级荣誉,其中2025年作为负责人带领团队斩获“挑战杯”全国大学生课外学术科技作品竞赛河南省省级一等奖。

26

帖子

0

提问

257

粉丝

关注
最新发布

鸿蒙实战:打造跨设备音乐播放器

2025-11-25 16:23:11    发布
热门推荐
地址:北京市朝阳区北三环东路三元桥曙光西里甲1号第三置业A座1508室 商务内容合作QQ:2291221 电话:13391790444或(010)62178877
版权所有:电脑商情信息服务集团 北京赢邦策略咨询有限责任公司
声明:本媒体部分图片、文章来源于网络,版权归原作者所有,我司致力于保护作者版权,如有侵权,请与我司联系删除
京ICP备:2022009079号-2
京公网安备:11010502051901号
ICP证:京B2-20230255