ArkUI 焦点处理:键盘和遥控器用户也要走得通

举报
蓝瘦的蜕变 发表于 2026/10/15 09:18:05 2026/10/15
【摘要】 今天我们给三张卡片加上焦点能力。 很多页面只考虑手指点击,结果一接键盘、遥控器或者无障碍操作,页面就不知道该往哪走。焦点处理解决的就是这个问题:谁能获得焦点、焦点顺序是什么、获得焦点后有没有明显边框。 参考文档: https://developer.huawei.com/consumer/cn/doc/harmonyo

ArkUI 焦点处理:键盘和遥控器用户也要走得通

今天我们给三张卡片加上焦点能力。

很多页面只考虑手指点击,结果一接键盘、遥控器或者无障碍操作,页面就不知道该往哪走。焦点处理解决的就是这个问题:谁能获得焦点、焦点顺序是什么、获得焦点后有没有明显边框。

参考文档:

  • https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-interaction-development-guide-overview

让组件可以获得焦点

.focusable(true)
.focusOnTouch(true)
.tabIndex(1)

focusable(true) 让组件进入焦点系统,focusOnTouch(true) 让点击也能把焦点带过去,tabIndex 用来控制基础顺序。

焦点边框要清楚

.focusBox({
  strokeColor: ColorMetrics.resourceColor('#FACC15'),
  strokeWidth: LengthMetrics.vp(3),
  margin: LengthMetrics.vp(4)
})

这里要注意类型:focusBox 需要 ColorMetrics 和 LengthMetrics,不是随手塞一个字符串或数字。

你平时会不会用键盘测页面?如果从来不测,很多焦点问题可能只有用户接上外设后才暴露。

完整示例代码

文件位置:entry/src/main/ets/pages/arkUI/interaction/ArkUIFocusDemo.ets

import { ColorMetrics, LengthMetrics } from '@kit.ArkUI';

@Entry
@Component
struct ArkUIFocusDemo {
  @State focusText: string = '用键盘 Tab、方向键或点击卡片,观察焦点变化'
  @State focusedName: string = '暂无'

  private showTip(message: string): void {
    this.getUIContext().getPromptAction().showToast({
      message: message,
      duration: 1200,
      bottom: 120
    })
  }

  @Builder
  sectionTitle(title: string, desc: string) {
    Column({ space: 6 }) {
      Text(title)
        .fontSize(19)
        .fontWeight(FontWeight.Bold)
        .fontColor('#111827')
      Text(desc)
        .fontSize(13)
        .fontColor('#6B7280')
        .lineHeight(20)
    }
    .width('100%')
    .alignItems(HorizontalAlign.Start)
  }

  @Builder
  focusCard(title: string, desc: string, name: string, color: string, tabIndex: number, defaultFocus: boolean) {
    Column({ space: 10 }) {
      Text(title)
        .fontSize(18)
        .fontWeight(FontWeight.Bold)
        .fontColor('#FFFFFF')
      Text(desc)
        .fontSize(13)
        .fontColor('#E5E7EB')
        .lineHeight(20)
    }
    .width('100%')
    .layoutWeight(1)
    .height(120)
    .padding(16)
    .borderRadius(16)
    .backgroundColor(color)
    .justifyContent(FlexAlign.Center)
    .alignItems(HorizontalAlign.Start)
    .focusable(true)
    .focusOnTouch(true)
    .defaultFocus(defaultFocus)
    .tabIndex(tabIndex)
    .focusBox({
      strokeColor: ColorMetrics.resourceColor('#FACC15'),
      strokeWidth: LengthMetrics.vp(3),
      margin: LengthMetrics.vp(4)
    })
    .onFocus(() => {
      this.focusedName = name
      this.focusText = `${name} 获得焦点`
      this.showTip(`${name} 获得焦点`)
    })
    .onBlur(() => {
      this.focusText = `${name} 失去焦点`
    })
  }

  build() {
    Scroll() {
      Column({ space: 22 }) {
        Column({ space: 8 }) {
          Text('ArkUI 焦点处理')
            .fontSize(28)
            .fontWeight(FontWeight.Bold)
            .fontColor('#111827')
          Text('键盘和遥控器用户也要走得通')
            .fontSize(16)
            .fontColor('#4B5563')
          Text('焦点不是 TV 才需要。键盘、遥控器、无障碍操作都会依赖焦点顺序和焦点样式。')
            .fontSize(14)
            .fontColor('#6B7280')
            .lineHeight(22)
        }
        .width('100%')
        .alignItems(HorizontalAlign.Start)

        this.sectionTitle('三张可聚焦卡片', '第一张设置 defaultFocus,三张卡片用 tabIndex 控制顺序,并用 focusBox 明确焦点边框。')
        Row({ space: 10 }) {
          this.focusCard('第一项', 'defaultFocus + tabIndex 1', '第一项', '#2563EB', 1, true)
          this.focusCard('第二项', 'tabIndex 2', '第二项', '#0F766E', 2, false)
          this.focusCard('第三项', 'tabIndex 3', '第三项', '#C2410C', 3, false)
        }
        .width('100%')

        Column({ space: 8 }) {
          Text(`当前焦点:${this.focusedName}`)
            .fontSize(16)
            .fontWeight(FontWeight.Bold)
            .fontColor('#111827')
          Text(this.focusText)
            .fontSize(14)
            .fontColor('#475569')
            .lineHeight(22)
        }
        .width('100%')
        .padding(16)
        .borderRadius(14)
        .backgroundColor('#FFFFFF')
        .border({ width: 1, color: '#E5E7EB' })
      }
      .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个月内不可修改。