HarmonyOS ArkTS 按钮状态样式库:主按钮 / 次按钮 / 危险按钮(可直接复制用,带 stateStyles + 工程化写法)

39 阅读4分钟

HarmonyOS ArkTS 按钮状态样式库:主按钮 / 次按钮 / 危险按钮(可直接复制用,带 stateStyles + 工程化写法)

一起来构建生态吧~

这份是我按“真实项目能落地”的思路整理的按钮样式库:主按钮(Primary)/ 次按钮(Secondary)/ 危险按钮(Danger) 。 写法上我推荐用 @Extend(Button) + stateStyles 组合:

  • @Extend 让你在页面里直接 .primaryBtn() / .secondaryBtn() / .dangerBtn()
  • stateStyles 负责按下/获焦/禁用的多态表现(不用你写 onTouch/onFocus)

你复制完,页面里写按钮就会变得非常干净: Button('提交', ...).primaryBtn() 这种。


0. 设计目标(我做按钮样式时最在意的 5 件事)

  1. 正常态要“明确” :主按钮一眼就知道是主要操作
  2. 按下态要“有反馈” :不然用户会怀疑没点到
  3. 获焦态要“能用在 TV/车机/键盘” :焦点可视化必须清晰
  4. 禁用态要“像禁用” :不只是变灰,还要显得不可点击
  5. 风格统一:圆角、字号、间距一致,后期改版才不崩

1. 推荐落地方式:一个文件搞定三种按钮

你可以新建一个文件,比如:

  • entry/src/main/ets/styles/button.extend.ets

然后把下面内容直接放进去。


2. 代码:按钮基础规范(高度、圆角、字号等)

我会先做一个“基础按钮规范”,因为项目里按钮的高度、圆角、字体不统一,后面维护会很痛。

建议规范(你也可以按你项目改)

  • 高度:44(移动端常用)
  • 圆角:12(比较现代)
  • 字体:16,略加粗
  • 宽度:默认 100%(表单页最常见)

3. 主按钮 Primary(最常用)

3.1 主按钮应该是什么样?

主按钮一般承担“提交/保存/确认/下一步”,所以:

  • 颜色饱和、对比强
  • 文本白色
  • 按下变深
  • 获焦给清晰描边(尤其 TV/车机)

3.2 主按钮 Extend + stateStyles

 // entry/src/main/ets/styles/button.extend.ets
 ​
 @Extend(Button)
 export function primaryBtn() {
   this
     .height(44)
     .width('100%')
     .borderRadius(12)
     .stateStyles({
       normal: {
         .backgroundColor('#2F7BFF')      // 主色蓝
         .fontColor('#FFFFFF')
         .fontSize(16)
         .fontWeight(FontWeight.Medium)
       },
       pressed: {
         .backgroundColor('#1F5FE0')      // 按下更深
       },
       focused: {
         .border({ width: 2, color: '#FFCC00' }) // 获焦描边(黄)
       },
       disabled: {
         .backgroundColor('#CFCFCF')
         .fontColor('#8A8A8A')
       }
     })
 }

3.3 页面里怎么用(很“顺手”)

 Button('提交', () => {
   // submit...
 }).primaryBtn()

4. 次按钮 Secondary(更克制,但要清晰)

4.1 次按钮通常用在哪?

比如:

  • “取消”
  • “稍后再说”
  • “查看详情”(不是主要动作)

它不应该抢主按钮的注意力,但也不能“像个链接一样弱”。

常见做法:

  • 浅底 + 深字
  • 或者 描边按钮(ghost)
  • 按下态变浅灰/加深描边

4.2 次按钮 Extend + stateStyles(描边方案更耐用)

 @Extend(Button)
 export function secondaryBtn() {
   this
     .height(44)
     .width('100%')
     .borderRadius(12)
     .stateStyles({
       normal: {
         .backgroundColor('#FFFFFF')
         .fontColor('#2F7BFF') // 用主色做文字
         .fontSize(16)
         .fontWeight(FontWeight.Medium)
         .border({ width: 1, color: '#2F7BFF' })
       },
       pressed: {
         .backgroundColor('#EEF4FF')      // 轻微填充,告诉用户“按下了”
       },
       focused: {
         .border({ width: 2, color: '#FFCC00' }) // 获焦描边
       },
       disabled: {
         .backgroundColor('#FFFFFF')
         .fontColor('#B0B0B0')
         .border({ width: 1, color: '#D9D9D9' })
       }
     })
 }

4.3 页面用法

 Button('取消', () => {
   // cancel...
 }).secondaryBtn()

5. 危险按钮 Danger(用得少,但必须“像危险”)

5.1 危险按钮的典型场景

  • 删除
  • 清空
  • 解绑
  • 退出登录(如果产品定义为危险操作)

危险按钮的设计原则:

  • 红色要明确
  • 按下更深
  • 禁用更灰
  • 尽量不要和主按钮同屏并排抢焦点(除非产品强要求)

5.2 危险按钮 Extend + stateStyles

 @Extend(Button)
 export function dangerBtn() {
   this
     .height(44)
     .width('100%')
     .borderRadius(12)
     .stateStyles({
       normal: {
         .backgroundColor('#FF4D4F')   // 常见危险红
         .fontColor('#FFFFFF')
         .fontSize(16)
         .fontWeight(FontWeight.Medium)
       },
       pressed: {
         .backgroundColor('#D9363E')   // 按下更深
       },
       focused: {
         .border({ width: 2, color: '#FFCC00' }) // 统一焦点色,体验一致
       },
       disabled: {
         .backgroundColor('#E6E6E6')
         .fontColor('#9B9B9B')
       }
     })
 }

5.3 页面用法

 Button('删除账号', () => {
   // delete...
 }).dangerBtn()

6. 推荐的“按钮组”排版(真实页面最常见)

6.1 主 + 次(表单页经典)

 Column({ space: 12 }) {
   Button('保存', () => {}).primaryBtn()
   Button('取消', () => {}).secondaryBtn()
 }

6.2 危险按钮单独放(别和主按钮挤一起)

 Column({ space: 12 }) {
   Button('退出登录', () => {}).dangerBtn()
 }

7. 我个人会加的两个“细节优化”(很像真实项目)

7.1 Loading 态(主按钮经常需要)

建议你在业务层做一个 @State loading,然后:

  • loading 时 enabled(false)
  • 文案变成“提交中…”
 @State submitting: boolean = false
 ​
 Button(this.submitting ? '提交中…' : '提交', () => {
   this.submitting = true
   // async submit...
 })
   .enabled(!this.submitting)
   .primaryBtn()

7.2 小按钮/紧凑按钮(列表页很常用)

你可以再做一个 primaryBtnSmall(),高度 36、字号 14,复用思路一致。


8. 最后给你一句“像人写的总结”

按钮样式这种东西,写一遍看着没啥,但项目一大就会发现: 统一按钮规范 = 省下最多的维护时间

尤其是 pressed / focused / disabled 这三种状态, 你如果不用 stateStyles 去统一,而是到处手写 onTouch/onFocus,后面改版基本等于灾难。