在HarmonyOS 6购物比价或电商类应用中,商品图画廊常用 Stack叠放信息层——左上角标"新品"、右上角标"限时折扣"、左下角标"仅剩3件"、右下角标"月销2k+"。很多新手把四个 Text直接塞进 Stack发现全部叠在正中央或左上角,不知道如何用最少嵌套让子组件分别"粘"到四个角。

官方行业实践明确答复:用 Row(水平两端对齐)+ Column(垂直两端对齐)​ 嵌套,给 Row 设 width('100%')、Column 设 height('100%'),即可把左上/右上放上行 Row、左下/右下放下行 Row。本文将完整实现此方案。


一、现象:Stack内四个Text全叠一起

1. 问题现场

// ❌ 四个Text直接放Stack,默认都 align=TopStart → 叠在左上角互相遮挡
Stack() {
  Text('新品').fontSize(12).fontColor('#4CAF50').border(...)
  Text('限时折扣').fontSize(12).fontColor('#FF5722').border(...)
  Text('仅剩3件').fontSize(11).fontColor('#999')
  Text('月销2k+').fontSize(11).fontColor('#999')
}
.width(300).height(300)

期望四角各居一角,实际四个标签重叠在左上角。

2. 根因揭秘

Stack子组件默认对齐到 Alignment.TopStart(左上),不会自动分散。需人为构造两维对齐结构:

  • 水平方向:用一个 RowjustifyContent: SpaceBetween+ width('100%')→ 左端放左上角内容、右端放右上角内容

  • 垂直方向:外层包 ColumnjustifyContent: SpaceBetween+ height('100%')→ 首行放上面 Row(左上+右上)、末行放下面 Row(左下+右下)

此结构即官方FAQ推荐解法,通用且代码量少。


二、完整实现——商品图四角标签

// pages/GoodsImageWithCorners.ets
import { common } from '@kit.AbilityKit';

@Entry
@Component
struct GoodsImageCornerPage {
  build() {
    Column({ space: 24 }) {
      Text('商品图画廊 · 四角信息分布')
        .fontSize(18)
        .fontWeight(FontWeight.Bold)
        .alignSelf(HorizontalAlign.Start)
        .margin({ left: 16, top: 16 })

      // ===== Stack 商品图 + 四角标签 =====
      Stack() {
        // --- 底层:商品图 ---
        Image($r('app.media.prod_01'))
          .width('100%')
          .height(300)
          .objectFit(ImageFit.Cover)
          .borderRadius(12)

        // --- 四角标签层(核心结构)---
        Column() {
          // 上行:左上 + 右上
          Row() {
            // 左上 — 新品标签
            this.cornerTag('新品', '#4CAF50', '#E8F5E9')

            Blank()   // 推右侧内容到右端

            // 右上 — 折扣标签
            this.cornerTag('限时折扣', '#FF5722', '#FFF3E0')
          }
          .width('100%')

          Blank()   // 推下行 Row 到底

          // 下行:左下 + 右下
          Row() {
            // 左下 — 库存紧张
            this.cornerTag('仅剩3件', '#F44336', 'rgba(255,255,255,0.85)')

            Blank()

            // 右下 — 销量
            this.cornerTag('月销2k+', '#757575', 'rgba(255,255,255,0.85)')
          }
          .width('100%')
        }
        .width('100%')
        .height('100%')
        .padding(10)   // 标签距边缘间距
      }
      .width('90%')
      .height(300)
      .borderRadius(12)
      .clip(true)      // 标签不超出圆角
      .alignSelf(HorizontalAlign.Center)
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#F5F6F8')
  }

  // ===== 角标 Builder =====
  @Builder
  cornerTag(text: string, txtColor: string, bg: string) {
    Text(text)
      .fontSize(11)
      .fontColor(txtColor)
      .padding({ horizontal: 8, vertical: 3 })
      .backgroundColor(bg)
      .borderRadius(4)
      .maxLines(1)
  }
}

关键结构解读

Stack
 └── Column (height:100%, justifyContent:SpaceBetween)   ← 垂直两端
      ├── Row (width:100%, justifyContent:SpaceBetween)  ← 水平两端
      │    ├── [左上] 新品
      │    └── [右上] 限时折扣
      └── Row (width:100%, justifyContent:SpaceBetween)
           ├── [左下] 仅剩3件
           └── [右下] 月销2k+
  • Blank()在 Row 中起 SpaceBetween作用(推开两侧子组件)

  • ColumnSpaceBetween+ height('100%')把两行 Row 推到顶和底

  • Stack 内 padding(10)控制标签距图片边缘距离,可微调

  • 外层 clip(true)确保标签不溢出 borderRadius(12)圆角


三、避坑指南

问题

原因

修复

标签仍叠在左上

直接放 Stack 未嵌套 Row/Column

按上文 Column{Row,Blank,Row} 结构包

右上/右下不贴右边缘

Row 未设 width('100%')

每个 Row 必须 width('100%')

左下/右下不贴底部

Column 未设 height('100%')或忘了 SpaceBetween

Column height('100%')+ justifyContent:SpaceBetween

标签被图片盖住

层级顺序反了——标签应在图片(后渲染在上层)

Stack 中子组件顺序:先 Image → 后标签 Column

想只显示部分角标

条件渲染包裹对应 Builder 即可 {showNew && this.cornerTag(...)}

@State showXxx控制显隐


四、总结:Stack四角分布SOP

  1. Stack 内顺序:先背景(Image)→ 后信息层(Column)

  2. 信息层结构Column(height:100%, SpaceBetween) → Row(width:100%, SpaceBetween) 上行 + Row 下行

  3. 对角内容:左上/右上放上行 Row 左右端,左下/右下放下行 Row 左右端(Blank()推开)

  4. 微调padding控距边缘、clip(true)配合 borderRadius

核心法则:HarmonyOS 6 中 Stack 四角分布 = "Column(SpaceBetween) 包两个 Row(SpaceBetween)",不用手动算坐标,纯声明式对齐搞定。

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任。

Logo

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

更多推荐