ArkUI stateStyles:按下、聚焦、禁用,不该都长一个样

举报
蓝瘦的蜕变 发表于 2026/09/22 17:51:52 2026/09/22
【摘要】 今天我们用 stateStyles 给按钮的不同状态配不同外观。 很多新手写按钮时,只写 normal 样式。结果按下、聚焦、禁用都差不多,用户很难判断当前控件到底能不能点、有没有被选中。stateStyles 解决的是这个视觉反馈问题。 参考文档:组件扩展 先说结论 stateStyles 适合: 按下时给反馈。 聚

ArkUI stateStyles:按下、聚焦、禁用,不该都长一个样

今天我们用 stateStyles 给按钮的不同状态配不同外观。

很多新手写按钮时,只写 normal 样式。结果按下、聚焦、禁用都差不多,用户很难判断当前控件到底能不能点、有没有被选中。stateStyles 解决的是这个视觉反馈问题。

参考文档:组件扩展

先说结论

stateStyles 适合:

  • 按下时给反馈。
  • 聚焦时给键盘或遥控器用户提示。
  • 禁用时让控件一眼看出不可用。

不适合:

  • 存业务状态。
  • 做表单提交。
  • 替代状态管理。

这篇我们只讲外观变化。

直接在 stateStyles 里写状态分支

Button('Demo')
  .stateStyles({
    normal: {
      .backgroundColor('#2563EB')
      .scale({ x: 1, y: 1 })
    },
    pressed: {
      .backgroundColor('#1D4ED8')
      .scale({ x: 0.96, y: 0.96 })
    }
  })

这里直接在 stateStyles 的状态分支里写通用属性,当前编译器更稳。像 fontColor 这种组件专属属性,要写回具体 Button 上。

给按钮绑定 stateStyles

Button('按住或用键盘聚焦试试')
  .stateStyles({
    normal: {
      .backgroundColor('#2563EB')
    },
    pressed: {
      .backgroundColor('#1D4ED8')
    },
    focused: {
      .backgroundColor('#7C3AED')
    }
  })

normal 是普通态,pressed 是按压态,focused 是聚焦态。

聚焦态通常在外接键盘、遥控器这类输入方式下更明显。手机触摸场景下,你大概率更容易看到 pressed。

页面效果

Demo 里有两块:

  • 第一块展示正常、按下、聚焦。
  • 第二块展示禁用态。

禁用态这里不做业务判断,只固定展示 enabled(false)。真实项目里,最好配合文案说明为什么不可用,别只靠变灰让用户猜。

你们平时写按钮时,会专门处理 disabled 和 focused 吗?如果之前没有,这一篇可以拿你自己的主按钮试着改一次。

完整示例代码

文件位置:entry/src/main/ets/pages/arkUI/custom/ArkUIStateStylesDemo.ets

@Entry
@Component
struct ArkUIStateStylesDemo {
  @Builder
  HeaderBlock() {
    Column({ space: 8 }) {
      Text('ArkUI stateStyles')
        .fontSize(28)
        .fontWeight(700)
        .fontColor('#111827')
      Text('按下、聚焦、禁用,不该都长一个样')
        .fontSize(16)
        .fontColor('#4B5563')
      Text('stateStyles 用来描述组件在不同内部状态下的外观。它处理的是视觉反馈,不是业务状态。')
        .fontSize(14)
        .fontColor('#6B7280')
        .lineHeight(22)
    }
    .width('100%')
    .alignItems(HorizontalAlign.Start)
  }

  build() {
    Scroll() {
      Column({ space: 20 }) {
        this.HeaderBlock()

        Column({ space: 14 }) {
          Text('正常、按下、聚焦')
            .fontSize(18)
            .fontWeight(700)
            .fontColor('#111827')
          Button('按住或用键盘聚焦试试')
            .height(46)
            .borderRadius(23)
            .fontSize(15)
            .fontWeight(700)
            .fontColor('#FFFFFF')
            .focusable(true)
            .stateStyles({
              normal: {
                .backgroundColor('#2563EB')
                .scale({ x: 1, y: 1 })
              },
              pressed: {
                .backgroundColor('#1D4ED8')
                .scale({ x: 0.96, y: 0.96 })
              },
              focused: {
                .backgroundColor('#7C3AED')
                .border({ width: 2, color: '#C4B5FD' })
              }
            })
          Text('按压时颜色会变深,聚焦时会出现另一套样式。不同设备上的聚焦触发方式可能不一样,外接键盘会更明显。')
            .fontSize(14)
            .fontColor('#4B5563')
            .lineHeight(21)
        }
        .width('100%')
        .padding(16)
        .borderRadius(18)
        .backgroundColor('#FFFFFF')
        .border({ width: 1, color: '#E5E7EB' })
        .alignItems(HorizontalAlign.Start)

        Column({ space: 14 }) {
          Text('禁用态')
            .fontSize(18)
            .fontWeight(700)
            .fontColor('#111827')
          Button('暂不可用')
            .height(46)
            .borderRadius(23)
            .fontSize(15)
            .fontWeight(700)
            .fontColor('#6B7280')
            .enabled(false)
            .stateStyles({
              disabled: {
                .backgroundColor('#D1D5DB')
              }
            })
          Text('禁用态应该一眼看出来,但也别只靠颜色表达,真实业务里还要配合文案和可访问性说明。')
            .fontSize(14)
            .fontColor('#4B5563')
            .lineHeight(21)
        }
        .width('100%')
        .padding(16)
        .borderRadius(18)
        .backgroundColor('#FFFFFF')
        .border({ width: 1, color: '#E5E7EB' })
        .alignItems(HorizontalAlign.Start)

        Text('这一页只讲组件内部状态的样式变化。真正的数据选中、表单提交、业务禁用原因,应该留给状态管理和业务逻辑处理。')
          .width('100%')
          .padding(16)
          .borderRadius(16)
          .backgroundColor('#F8FAFC')
          .fontSize(14)
          .fontColor('#4B5563')
          .lineHeight(22)
      }
      .width('100%')
      .padding(24)
      .alignItems(HorizontalAlign.Start)
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#F8FAFC')
  }
}
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

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

全部回复

上滑加载中

设置昵称

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

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

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