ArkUI Checkbox:多选不打架,选择才像选择

举报
蓝瘦的蜕变 发表于 2026/08/24 14:40:22 2026/08/24
【摘要】 这篇我们单独看 Checkbox。 上一篇 Toggle 里已经见过 Checkbox 形态,但那只是为了分清几种开关外观。这一篇不绕了,我们就盯着真正的 Checkbox 组件:单个勾选、多个独立选择、颜色和禁用态。 先说清楚边界:这篇不讲成组管理,也不做全选、反选、列表刷新和表单提交。那些内容以后会放到对应章节。我

ArkUI Checkbox:多选不打架,选择才像选择

这篇我们单独看 Checkbox

上一篇 Toggle 里已经见过 Checkbox 形态,但那只是为了分清几种开关外观。这一篇不绕了,我们就盯着真正的 Checkbox 组件:单个勾选、多个独立选择、颜色和禁用态。

先说清楚边界:这篇不讲成组管理,也不做全选、反选、列表刷新和表单提交。那些内容以后会放到对应章节。我们先把一个勾选框本身写稳。

参考文档:

  • https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkui
  • https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-ui-development

单个 Checkbox 先讲语义

Checkbox 适合“我选择了这个选项”。它不是持续生效的开关,所以像“我已阅读并同意服务说明”这种一次确认,用它比用 Switch 更自然。

Checkbox({ name: '我已阅读并同意服务说明' })
  .select(true)
  .selectedColor('#0F766E')
  .unselectedColor('#94A3B8')

name 用来标识这个 Checkbox。select(true) 让它一开始就是选中状态。

这里最容易写错的不是代码,而是文案。旁边不要只写“同意”,最好写完整一点,让用户知道勾上以后到底代表什么。这个细节看起来小,但放到真实页面里,能少很多误点。

多个 Checkbox 可以彼此独立

如果几个选项之间没有互斥关系,就可以直接放多个 Checkbox

Checkbox({ name: '消息通知' })
  .select(true)
  .selectedColor('#2563EB')
  .unselectedColor('#CBD5E1')

Checkbox({ name: '活动提醒' })
  .select(false)
  .selectedColor('#2563EB')
  .unselectedColor('#CBD5E1')

比如消息通知、活动提醒、安全告警,它们可以选一个,也可以选多个。这里不需要急着上成组选中逻辑。

成组管理不是不能用,只是它适合更复杂的场景。我们这一篇先讲独立选项,越少牵扯越容易看明白。

颜色别只盯选中态

selectedColor 很常用,能让勾选框跟页面主色走在一起。

Checkbox({ name: '加入本周清单' })
  .select(true)
  .selectedColor('#7C3AED')
  .unselectedColor('#C4B5FD')

unselectedColor 也别忽略。未选中颜色太重,页面会显得每个框都在抢注意力;太浅,又可能让用户看不清边界。

案例里把选中态做得更明确,未选中态收得轻一点。不是说只能这么配色,重点是:选中和未选中都要被设计,不要只改一半。

禁用态要解释为什么不能改

enabled(false) 可以让 Checkbox 变成不可操作状态。

Checkbox({ name: '由组织统一开启' })
  .select(true)
  .selectedColor('#64748B')
  .unselectedColor('#CBD5E1')
  .enabled(false)

禁用态最怕只变灰,不解释。用户点不了,会先怀疑自己是不是没点准,或者页面是不是出了问题。

所以案例里把原因写在文案里:比如“当前账号属于企业空间,这项由管理员统一配置”。这句话不花哨,但很有用。

看案例时盯这几处

打开案例页后,我们不用急着改状态,先看几个视觉和语义点:

  • 单个 Checkbox 是否表达了一次确认,而不是长期设置。
  • 多个 Checkbox 是否是彼此独立的选择,没有强行绑成一组。
  • 选中颜色和未选中颜色是否都被处理过。
  • 禁用态是否不仅变灰,还解释了不能操作的原因。

这篇不跑 hvigor。你在 DevEco Studio 里打开案例页,看这些勾选项的摆放和文案就够了。

如果你现在手里有一个设置页,可以挑一组多选项看看:它们是真的可以多选,还是其实应该做成单选?这个判断很常见,也很容易一开始就写偏。

完整示例代码

文件位置:entry/src/main/ets/pages/arkUI/basic/ArkUICheckboxDemo.ets

@Entry
@Component
struct ArkUICheckboxDemo {
  @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)
  }

  @Builder
  optionText(title: string, desc: string, enabled: boolean) {
    Column({ space: 4 }) {
      Text(title)
        .width('100%')
        .fontSize(15)
        .fontWeight(700)
        .fontColor(enabled ? '#0F172A' : '#94A3B8')

      Text(desc)
        .width('100%')
        .fontSize(12)
        .fontColor(enabled ? '#64748B' : '#94A3B8')
        .lineHeight(18)
    }
    .alignItems(HorizontalAlign.Start)
    .layoutWeight(1)
  }

  @Builder
  checkboxRow(title: string, desc: string, selected: boolean, enabled: boolean, selectedColor: string,
    unselectedColor: string, borderColor: string) {
    Row({ space: 12 }) {
      Checkbox({ name: title })
        .select(selected)
        .selectedColor(selectedColor)
        .unselectedColor(unselectedColor)
        .enabled(enabled)

      this.optionText(title, desc, enabled)
    }
    .width('100%')
    .height(66)
    .padding({ left: 14, right: 14, top: 12, bottom: 12 })
    .backgroundColor(enabled ? '#FFFFFF' : '#F1F5F9')
    .border({ width: 1, color: enabled ? borderColor : '#CBD5E1' })
    .borderRadius(8)
  }

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

        Text('多选不打架,选择才像选择')
          .width('100%')
          .fontSize(22)
          .fontWeight(700)
          .fontColor('#111827')

        Text('这一页只看 Checkbox 自己:单个勾选、多个独立选项、颜色和禁用态。复杂选择逻辑、全选反选和状态刷新,先不放进来。')
          .width('100%')
          .fontSize(14)
          .fontColor('#64748B')
          .lineHeight(22)

        Column({ space: 12 }) {
          this.sectionTitle('单个 Checkbox 先把语义说清楚', '它不是持续开关,而是“我选择了这个选项”。旁边文案最好直接说明选中以后代表什么。')

          this.checkboxRow('我已阅读并同意服务说明', '适合一次确认,不适合做成 Switch。', true, true, '#0F766E',
            '#94A3B8', '#BBF7D0')
        }
        .width('100%')
        .padding(16)
        .backgroundColor('#F0FDF4')
        .borderRadius(8)

        Column({ space: 12 }) {
          this.sectionTitle('多个 Checkbox 可以彼此独立', '这几项没有互斥关系,用户可以选一个、选多个,也可以都不选。先别急着加成组管理。')

          this.checkboxRow('消息通知', '收到评论、点赞和系统提醒时通知我。', true, true, '#2563EB',
            '#CBD5E1', '#BFDBFE')
          this.checkboxRow('活动提醒', '有活动开始前,再额外提醒一次。', false, true, '#2563EB',
            '#CBD5E1', '#BFDBFE')
          this.checkboxRow('安全告警', '登录异常、密码修改这类消息保持勾选。', true, true, '#2563EB',
            '#CBD5E1', '#BFDBFE')
        }
        .width('100%')
        .padding(16)
        .backgroundColor('#EFF6FF')
        .borderRadius(8)

        Column({ space: 12 }) {
          this.sectionTitle('颜色别只改选中态', '选中颜色能强调重点,未选中颜色也要收住,不然页面会显得每个框都在抢注意力。')

          this.checkboxRow('加入本周清单', '选中态用紫色,适合和页面主色保持一致。', true, true, '#7C3AED',
            '#C4B5FD', '#DDD6FE')
          this.checkboxRow('稍后再看', '未选中态用浅灰紫,能看见边界,但不会太重。', false, true, '#7C3AED',
            '#C4B5FD', '#DDD6FE')
        }
        .width('100%')
        .padding(16)
        .backgroundColor('#F5F3FF')
        .borderRadius(8)

        Column({ space: 12 }) {
          this.sectionTitle('禁用态要顺手告诉用户原因', '不能改的时候,不要只把框变灰。旁边文案多写一句原因,用户就不会以为页面坏了。')

          this.checkboxRow('由组织统一开启', '当前账号属于企业空间,这项由管理员统一配置。', true, false, '#64748B',
            '#CBD5E1', '#CBD5E1')
          this.checkboxRow('试用期结束后可选', '这个选项暂时不可用,正式开通后再开放。', false, false, '#64748B',
            '#CBD5E1', '#CBD5E1')
        }
        .width('100%')
        .padding(16)
        .backgroundColor('#F8FAFC')
        .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个月内不可修改。