鸿蒙无障碍开发完整指南【1】

2025-06-28 13:39:20
104次阅读
0个评论

第一篇:无障碍开发基础

1.1 什么是无障碍开发

无障碍开发是指让应用程序能够被所有用户使用,包括有视觉、听觉、运动或认知障碍的用户。在鸿蒙系统中,无障碍功能就像是为应用装上了"翻译器",让屏幕阅读器、语音助手等辅助技术能够理解和操作我们的应用。

无障碍开发的重要意义:

  • 社会责任:让更多人能够平等地使用数字产品
  • 法律合规:符合各国无障碍法律法规要求
  • 用户体验:提升所有用户的使用体验
  • 商业价值:扩大用户群体,提高产品竞争力

鸿蒙系统支持的无障碍技术:

  • 屏幕阅读器:将屏幕内容转换为语音输出
  • 语音控制:通过语音命令操作应用
  • 放大镜功能:放大屏幕内容
  • 高对比度模式:增强视觉对比度
  • 开关控制:通过外部开关设备操作

1.2 无障碍属性详解

鸿蒙系统提供了丰富的无障碍属性,让开发者能够为组件添加无障碍支持。这些属性就像是给组件贴上"标签",告诉辅助技术这个组件是什么、做什么用的。

1.2.1 accessibilityGroup - 无障碍组

accessibilityGroup属性用于将多个相关的组件组合成一个无障碍单元。当设置为true时,屏幕阅读器会将整个组合视为一个整体,而不会分别读取每个子组件。

使用场景:

  • 卡片组件(包含标题、内容、按钮等)
  • 列表项(包含图标、文本、状态等)
  • 表单组(包含标签、输入框、提示等)
@Component
struct UserCard {
  @Prop userName: string = '张三'
  @Prop userAge: number = 25
  @Prop userStatus: string = '在线'

  build() {
    Row() {
      Image($r('app.media.avatar'))
        .width(50)
        .height(50)
        .borderRadius(25)
      
      Column() {
        Text(this.userName)
          .fontSize(16)
          .fontWeight(FontWeight.Bold)
        
        Text(`年龄: ${this.userAge}`)
          .fontSize(14)
          .margin({ top: 4 })
        
        Text(this.userStatus)
          .fontSize(12)
          .fontColor('#10B981')
      }
      .alignItems(HorizontalAlign.Start)
      .margin({ left: 12 })
    }
    .padding(16)
    .backgroundColor('#FFFFFF')
    .borderRadius(12)
    // 设置为无障碍组,屏幕阅读器会将整个卡片作为一个单元读取
    .accessibilityGroup(true)
    // 为整个组合提供描述性文本
    .accessibilityText(`用户卡片:${this.userName},年龄${this.userAge}岁,状态${this.userStatus}`)
  }
}

1.2.2 accessibilityText - 无障碍文本

accessibilityText属性为组件提供描述性文本,当组件没有可见文本或需要提供额外说明时特别有用。这就像是为组件配备了"解说员",告诉用户这个组件的作用。

使用原则:

  • 简洁明了,避免冗长描述
  • 描述组件的功能而非外观
  • 使用用户熟悉的术语
  • 避免重复已有的文本内容
@Component
struct IconButton {
  @Prop iconResource: Resource = $r('app.media.ic_favorite')
  @Prop isSelected: boolean = false
  @Prop onButtonClick?: () => void

  build() {
    Button() {
      Image(this.iconResource)
        .width(24)
        .height(24)
        .fillColor(this.isSelected ? '#FF4444' : '#999999')
    }
    .width(48)
    .height(48)
    .backgroundColor('transparent')
    // 为图标按钮提供无障碍文本,说明其功能
    .accessibilityText(this.isSelected ? '取消收藏' : '添加到收藏')
    .onClick(() => {
      if (this.onButtonClick) {
        this.onButtonClick()
      }
    })
  }
}

@Component
struct SearchInput {
  @State searchText: string = ''

  build() {
    Row() {
      Image($r('app.media.ic_search'))
        .width(20)
        .height(20)
        .margin({ left: 12 })
        // 为搜索图标提供无障碍文本
        .accessibilityText('搜索图标')
      
      TextInput({ placeholder: '请输入搜索关键词' })
        .layoutWeight(1)
        .backgroundColor('transparent')
        .border({ width: 0 })
        .onChange((value: string) => {
          this.searchText = value
        })
        // 为输入框提供更详细的无障碍说明
        .accessibilityText('搜索输入框,请输入要搜索的内容')
    }
    .width('100%')
    .height(44)
    .backgroundColor('#F5F5F5')
    .borderRadius(22)
  }
}

1.2.3 accessibilityDescription - 无障碍说明

accessibilityDescription属性提供组件的详细说明信息,通常用于补充accessibilityText,提供更多的上下文信息。

使用场景:

  • 复杂交互的说明
  • 状态变化的描述
  • 操作结果的提示
  • 重要提醒信息
@Component
struct ProgressIndicator {
  @Prop progress: number = 0 // 0-100
  @Prop taskName: string = '下载任务'

  build() {
    Column() {
      Text(this.taskName)
        .fontSize(16)
        .margin({ bottom: 8 })
      
      Progress({ value: this.progress, total: 100, type: ProgressType.Linear })
        .width('100%')
        .height(8)
        .backgroundColor('#E5E5E5')
        .color('#3B82F6')
        // 提供进度条的无障碍文本
        .accessibilityText(`${this.taskName}进度`)
        // 提供详细的进度说明
        .accessibilityDescription(`当前进度${this.progress}%,${this.progress === 100 ? '已完成' : '正在进行中'}`)
      
      Text(`${this.progress}%`)
        .fontSize(14)
        .fontColor('#666666')
        .margin({ top: 4 })
    }
    .width('100%')
    .padding(16)
  }
}

1.2.4 accessibilityLevel - 无障碍级别

accessibilityLevel属性用于设置组件在无障碍导航中的重要性级别,帮助屏幕阅读器确定焦点顺序和导航层次。

级别说明:

  • 'auto':根据组件不同会转换为"yes"或者"no"(默认值)
  • 'yes':当前组件可被无障碍辅助服务所识别
  • 'no':当前组件不可被无障碍辅助服务所识别
  • 'no-hide-descendants':当前组件及其所有子组件不可被无障碍辅助服务所识别

注意: 以下组件当accessibilityLevel设置成"auto"时,当前组件可被无障碍辅助服务所识别:Checkbox, CheckboxGroup, Gauge, Marquee, MenuItem, MenuItemGroup, Menu, Navigation, DatePicker, Progress, Radio, Rating, ScrollBar, Select, Slider, Stepper, Text, TextClock, TextPicker, TextTimer, TimePicker, Toggle, Web。

@Component
struct ArticlePage {
  @Prop title: string = '文章标题'
  @Prop content: string = '文章内容...'
  @Prop author: string = '作者'
  @Prop publishTime: string = '2024-01-01'

  build() {
    Scroll() {
      Column() {
        // 文章标题 - 最高优先级
        Text(this.title)
          .fontSize(24)
          .fontWeight(FontWeight.Bold)
          .margin({ bottom: 16 })
          .accessibilityLevel('yes') // 高优先级,确保被读取
          .accessibilityText(`文章标题:${this.title}`)
        
        // 文章元信息 - 中等优先级
        Row() {
          Text(`作者:${this.author}`)
            .fontSize(14)
            .fontColor('#666666')
          
          Text(`发布时间:${this.publishTime}`)
            .fontSize(14)
            .fontColor('#666666')
            .margin({ left: 16 })
        }
        .width('100%')
        .margin({ bottom: 20 })
        .accessibilityLevel('auto') // 自动级别
        .accessibilityGroup(true)
        .accessibilityText(`文章信息:作者${this.author},发布于${this.publishTime}`)
        
        // 文章内容 - 重要内容
        Text(this.content)
          .fontSize(16)
          .lineHeight(24)
          .accessibilityLevel('yes') // 确保内容被完整读取
          .accessibilityText(`文章正文:${this.content}`)
        
        // 装饰性分隔线 - 低优先级
        Divider()
          .margin({ top: 20, bottom: 20 })
          .accessibilityLevel('no') // 装饰性元素,不需要被读取
        
        // 操作按钮区域 - 重要操作
        Row() {
          Button('点赞')
            .margin({ right: 12 })
            .accessibilityLevel('yes')
            .accessibilityText('点赞按钮')
            .accessibilityDescription('点击为文章点赞')
          
          Button('分享')
            .margin({ right: 12 })
            .accessibilityLevel('yes')
            .accessibilityText('分享按钮')
            .accessibilityDescription('点击分享文章')
          
          Button('收藏')
            .accessibilityLevel('yes')
            .accessibilityText('收藏按钮')
            .accessibilityDescription('点击收藏文章')
        }
        .width('100%')
        .justifyContent(FlexAlign.Center)
      }
      .padding(20)
    }
    .width('100%')
    .height('100%')
  }
}

1.3 无障碍事件处理

除了静态属性,鸿蒙还提供了无障碍事件处理机制,让应用能够响应各种无障碍操作。

@Component
struct AccessibleButton {
  @State isPressed: boolean = false
  @State clickCount: number = 0
  @Prop buttonText: string = '点击按钮'

  build() {
    Button(this.buttonText)
      .width(200)
      .height(50)
      .backgroundColor(this.isPressed ? '#2563EB' : '#3B82F6')
      .accessibilityText(`${this.buttonText},已点击${this.clickCount}次`)
      .accessibilityDescription('点击执行操作')
      .onClick(() => {
        this.clickCount++
        // 提供操作反馈
        console.log(`按钮被点击,当前点击次数:${this.clickCount}`)
      })
      .onTouch((event: TouchEvent) => {
        if (event.type === TouchType.Down) {
          this.isPressed = true
        } else if (event.type === TouchType.Up) {
          this.isPressed = false
        }
      })
      // 监听无障碍焦点事件
      .onFocus(() => {
        console.log('按钮获得无障碍焦点')
      })
      .onBlur(() => {
        console.log('按钮失去无障碍焦点')
      })
  }
}

收藏00

登录 后评论。没有帐号? 注册 一个。