ArkUI clipShape:边角一裁,图片和卡片马上不土了

举报
蓝瘦的蜕变 发表于 2026/10/11 22:13:16 2026/10/11
【摘要】 这一篇我们只看 clipShape。它的作用很直接:把一个组件按指定形状裁掉。图片可以裁,文本标签可以裁,卡片也可以裁。 Demo 里有三种常见用法 第一种是圆形裁剪。头像、入口图标、圆形徽章,都可以用 CircleShape。 第二种是圆角矩形。我们用 RectShape 裁图片和标签。它适合那些“只想把边角收一下”

ArkUI clipShape:边角一裁,图片和卡片马上不土了

这一篇我们只看 clipShape。它的作用很直接:把一个组件按指定形状裁掉。图片可以裁,文本标签可以裁,卡片也可以裁。

Demo 里有三种常见用法

第一种是圆形裁剪。头像、入口图标、圆形徽章,都可以用 CircleShape。

Image($r('app.media.startIcon'))
  .width(96)
  .height(96)
  .objectFit(ImageFit.Cover)
  .clipShape(new CircleShape({ width: 96, height: 96 }))

第二种是圆角矩形。我们用 RectShape 裁图片和标签。它适合那些“只想把边角收一下”的场景,不需要额外再套一层遮罩。

第三种是 PathShape。如果只是普通圆角,没必要上它;但需要斜边、切角、异形卡片时,PathShape 会更自由。

clipShape 不只给图片用

这一点很容易被忽略。很多时候我们会把 clipShape 和图片绑定在一起想,其实普通 Text、Column 也能用。Demo 里的“新品”和“限时体验”两个标签就是文本裁剪出来的。

这篇没有继续讲网络图、rawfile、media、SVG 换色,因为那些已经放在 Image 文章里了。这里我们只关心一件事:组件显示区域怎么被裁成另一个形状。

你做页面时,最常想裁的是头像、封面图,还是卡片边角?不同场景对形状的克制程度不太一样,可以顺手试几个版本。

参考文档: https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-clip-shape

完整示例代码

文件位置:entry/src/main/ets/pages/arkUI/drawing/ArkUIClipShapeDemo.ets

import { CircleShape, PathShape, RectShape } from '@kit.ArkUI';

@Entry
@Component
struct ArkUIClipShapeDemo {
  @Builder
  sectionTitle(title: string, desc: string) {
    Column({ space: 4 }) {
      Text(title)
        .width('100%')
        .fontSize(16)
        .fontWeight(700)
        .fontColor('#0F172A')

      Text(desc)
        .width('100%')
        .fontSize(13)
        .fontColor('#64748B')
        .lineHeight(20)
    }
    .width('100%')
    .alignItems(HorizontalAlign.Start)
  }

  build() {
    Scroll() {
      Column({ space: 18 }) {
        Text('ArkUI clipShape')
          .width('100%')
          .fontSize(24)
          .fontWeight(700)
          .fontColor('#0F172A')

        Text('边角一裁,图片和卡片马上不土了')
          .width('100%')
          .fontSize(22)
          .fontWeight(700)
          .fontColor('#111827')

        Text('clipShape 负责把组件按指定形状裁掉。它不只用在图片上,文本标签、卡片、装饰块都能裁。')
          .width('100%')
          .fontSize(14)
          .fontColor('#64748B')
          .lineHeight(22)

        Column({ space: 12 }) {
          this.sectionTitle('圆形裁剪适合头像和图标', '图片本身是方的也没关系,CircleShape 会把显示区域裁成圆形。')

          Row({ space: 18 }) {
            Image($r('app.media.startIcon'))
              .width(96)
              .height(96)
              .objectFit(ImageFit.Cover)
              .clipShape(new CircleShape({ width: 96, height: 96 }))

            Column({ space: 6 }) {
              Text('CircleShape')
                .fontSize(16)
                .fontWeight(700)
                .fontColor('#0F172A')

              Text('头像、入口图标、圆形徽章都适合这么处理。')
                .fontSize(13)
                .fontColor('#64748B')
                .lineHeight(20)
            }
            .layoutWeight(1)
            .alignItems(HorizontalAlign.Start)
          }
          .width('100%')
          .alignItems(VerticalAlign.Center)
        }
        .width('100%')
        .padding(16)
        .backgroundColor('#EFF6FF')
        .borderRadius(8)

        Column({ space: 12 }) {
          this.sectionTitle('RectShape 可以裁出稳定圆角', '当你只想控制圆角,不想额外写一个遮罩层,RectShape 会更直接。')

          Image($rawfile('icon_dev.png'))
            .width('100%')
            .height(150)
            .objectFit(ImageFit.Cover)
            .clipShape(new RectShape({ width: '100%', height: 150, radius: 24 }))
        }
        .width('100%')
        .padding(16)
        .backgroundColor('#F0FDF4')
        .borderRadius(8)

        Column({ space: 12 }) {
          this.sectionTitle('文本标签也可以裁', '标签不是只能靠 borderRadius。用 clipShape 裁出来之后,视觉上会更像一个独立的小组件。')

          Row({ space: 12 }) {
            Text('新品')
              .fontSize(14)
              .fontWeight(700)
              .fontColor('#FFFFFF')
              .textAlign(TextAlign.Center)
              .width(82)
              .height(34)
              .backgroundColor('#7C3AED')
              .clipShape(new RectShape({ width: 82, height: 34, radius: 17 }))

            Text('限时体验')
              .fontSize(14)
              .fontWeight(700)
              .fontColor('#FFFFFF')
              .textAlign(TextAlign.Center)
              .width(118)
              .height(34)
              .backgroundColor('#0F766E')
              .clipShape(new RectShape({ width: 118, height: 34, radius: 17 }))
          }
          .width('100%')
        }
        .width('100%')
        .padding(16)
        .backgroundColor('#F5F3FF')
        .borderRadius(8)

        Column({ space: 12 }) {
          this.sectionTitle('PathShape 适合裁出一点个性', '如果只是圆角,RectShape 就够了。需要斜边、切角、异形卡片时,再换 PathShape。')

          Column({ space: 8 }) {
            Text('PathShape Card')
              .fontSize(18)
              .fontWeight(700)
              .fontColor('#9A3412')

            Text('这张卡片的上下边不是标准矩形,靠 PathShape 裁出来。')
              .fontSize(13)
              .fontColor('#9A3412')
              .lineHeight(20)
          }
          .width(280)
          .height(96)
          .padding({ left: 20, right: 20, top: 18, bottom: 16 })
          .backgroundColor('#FFEDD5')
          .clipShape(new PathShape({ commands: 'M0 20 L280 0 L280 78 L0 96 Z' }))
        }
        .width('100%')
        .padding(16)
        .backgroundColor('#FFF7ED')
        .borderRadius(8)
      }
      .width('100%')
      .padding(20)
      .alignItems(HorizontalAlign.Start)
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#FFFFFF')
  }
}
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。