HarmonyOS ArkUI 实现商品分类布局

发布于:2025-08-15 ⋅ 阅读:(15) ⋅ 点赞:(0)

基于上面的商品分类布局实现,我将分享几个HarmonyOS ArkUI开发中的关键技术点,这些技术在实际项目中应用广泛,掌握它们能帮助你构建更高效、更优质的应用。

1. 组件化与UI结构设计

ArkUI采用声明式UI范式,核心是组件化思想。在示例中:

  • 使用@Component@Entry装饰器定义页面组件,@Entry标识应用入口
  • 通过@Builder抽取可复用的UI片段(如homeBuildercategoryBuilder),实现代码分离和复用
  • 采用"容器组件+内容组件"的嵌套结构,如Column+Row构建整体布局,List+ListItem展示列表,Grid+GridItem实现网格布局
// 组件化的典型结构
@Component
struct CustomComponent {
  build() {
    // UI描述
  }
}

@Entry // 应用入口组件
@Component
struct Index {
  // 状态管理
  // 构建UI
  build() {}
  
  // 复用UI片段
  @Builder
  customBuilder() {}
}

2. 状态管理与UI联动

状态管理是声明式UI的核心,示例中主要使用了@State装饰器:

  • @State selectedCategoryId: number = 1定义了选中的分类ID,这是一个响应式状态
  • selectedCategoryId发生变化时,依赖它的UI部分会自动更新(如左侧分类的选中样式、右侧商品列表)
  • 状态变化通过事件触发(如onClick(() => { this.selectedCategoryId = item.id })
// 状态驱动UI的工作流程
1. 定义状态:@State selectedId: number = 1
2. UI绑定状态:backgroundColor(this.selectedId === item.id ? '#fff' : '#f5f5f5')
3. 事件修改状态:onClick(() => { this.selectedId = item.id })
4. 状态变化自动更新UI

3. 列表与网格布局技术

针对商品分类场景,灵活运用了两种常用布局:

  • List列表布局(左侧分类):

    • 适合展示线性排列的同类数据
    • 通过divider属性添加分割线,增强视觉区分
    • 自带滚动特性,适合长列表展示
  • Grid网格布局(右侧商品):

    • 适合展示卡片类数据,通过columnsTemplate定义列数('1fr 1fr'表示两列等宽)
    • 使用columnsGaprowsGap控制间距,实现整齐排列
    • 配合Scroll组件实现长列表滚动
// 网格布局核心配置
Grid() {
  ForEach(products, (product) => {
    GridItem() { /* 商品卡片 */ }
  })
}
.columnsTemplate('1fr 1fr') // 2列布局
.columnsGap(10) // 列间距
.rowsGap(10) // 行间距

4. 数据驱动与动态渲染

通过ForEach实现数据到UI的映射,这是处理列表数据的核心技术:

  • 语法:ForEach(数据源, item => 生成UI的函数, 键值生成函数)
  • 数据源变化时,UI会自动更新,无需手动操作DOM
  • 示例中通过getProductsByCategory方法根据选中分类动态返回商品数据,实现"分类切换-商品更新"的联动
// 动态渲染示例
ForEach(
  this.getProductsByCategory(this.selectedCategoryId), // 动态数据源
  (product) => { /* 渲染单个商品 */ }, 
  (product) => product.id.toString() // 唯一标识,优化性能
)

5. 交互设计与事件处理

良好的交互是提升用户体验的关键:

  • 通过onClick事件实现分类切换、商品点击等交互
  • 使用Tabs+TabContent实现页面切换,配合TabsController可编程控制切换
  • 视觉反馈:选中状态通过颜色、边框变化体现,点击区域足够大(符合移动端交互规范)
// 交互反馈示例
ListItem() {
  Text(item.name)
    .backgroundColor(this.selectedCategoryId === item.id ? '#fff' : '#f5f5f5')
    .borderLeft({
      width: this.selectedCategoryId === item.id ? 4 : 0,
      color: '#ff7d00'
    })
}
.onClick(() => {
  this.selectedCategoryId = item.id // 状态变更
})

6. 样式与视觉优化

通过细节样式提升界面质感:

  • 使用borderRadius实现圆角效果,增强卡片感
  • shadow属性添加轻微阴影,提升层次感(避免过度使用影响性能)
  • 统一配色方案,主色调(橙色#ff7d00)用于强调选中状态和价格
  • 合理的留白(paddingmargin)避免界面拥挤

这些技术点不仅适用于商品分类场景,也是HarmonyOS ArkUI开发的基础。在实际开发中,需根据具体场景灵活组合这些技术,同时注意性能优化(如合理设置ForEach的键值、避免过度嵌套等)。

在这里插入图片描述

@Component
@Entry
struct Index {
  @State
  arr: string[] =
    ['食品', '电器', '洗护', '女装', '手机', '健康', '男装', '美妆', '电脑', '运动', '内衣', '母婴', '食品', '电器',
      '洗护', '女装', '手机', '健康', '男装', '美妆', '电脑', '运动', '内衣', '母婴']

  build() {
    Tabs() {
      TabContent() {
        this.homeBuilder()
      }
      .tabBar("首页")

      TabContent() {
        Text("分类的内容")
      }
      .tabBar("分类")
    }
    .width("100%")
    .height("100%")
    .barPosition(BarPosition.End)
  }

  @Builder
  homeBuilder() {
    Column() {
      // 1
      Row({ space: 10 }) {
        Image($r("app.media.startIcon"))
          .width(30)
          .fillColor("#666")

        Search({ placeholder: "颈椎按摩器" })
          .layoutWeight(1)

      }
      .width("100%")
      .padding(10)
      .border({
        width: {
          bottom: 3
        }
      })

      //   2
      Row() {
        //   左侧 List 默认的宽度和高度  霸道
        // 把右侧给占满了
        List() {
          ForEach(this.arr, (item: string) => {
            ListItem() {
              Text(item)
                .padding(10)
            }
          })
        }
        .width(100)
        .backgroundColor(Color.Orange)

        //    右侧
        Scroll() {
          Column() {

          }
          .height("200%")
          .width("100%")
          .linearGradient({
            colors: [[Color.Yellow, 0], [Color.Green, 1]]
          })
        }.layoutWeight(1)
        .height("100%")
        .backgroundColor(Color.Pink)

      }
      .width("100%")
      .layoutWeight(1)
    }
    .width("100%")
    .height("100%")

    // .backgroundColor(Color.Yellow)
  }
}

网站公告

今日签到

点亮在社区的每一天
去签到