> 编写:[K0ST](https://github.com/K0ST) - 原文:[http://developer.android.com/training/accessibility/accessible-app.html](http://developer.android.com/training/accessibility/accessible-app.html)
本课程将教您:
1.
添加内容描述(_Content Descriptions_)
1.
设计焦点导航(_Focus Navigation_)
1.
触发可达性事件(_Accessibility Events_)
1.
测试你的程序
Android平台本身有一些专注可达性的特性,这些特性可以帮助你专门为那些视觉上或生理上有缺陷的用户在应用上做特别的优化。然而,正确的优化方式或最简单利用这个特性的方法往往不是那么显而易见的。本课程将给您演示如何利用和实现这些策略和平台的特性功能,构建一个更友好的具有可达性的Android应用。
### 添加内容描述
一个好的交互界面上的元素通常不需要特别使用一个标签来表明这个元素的作用。例如对于一个任务型应用来说,一个项目旁边的勾选框表达的意思就非常明确,或者对于一个文件管理应用,垃圾桶的图标表达的意思也非常清除。然而对于具有视觉障碍的用户来说,其他类型的UI交互提示是有必要的。
幸运的是,我们可以很轻松的给一个UI元素加上标签,这样类似于[TalkBack](https://play.google.com/store/apps/details?id=com.google.android.marvin.talkback)这样的基于语音的Accessibility Service就可以将标签的内容朗读出来。如果你的标签在整个应用的生命周期中不太可能会发生变化(_比如‘停止’或者‘购买’_),你就可以在XML布局文件中对_android:contentDescription_属性进行设置。代码如下:
~~~
<Button
android:id=”@+id/pause_button”
android:src=”@drawable/pause”
android:contentDescription=”@string/pause”/>
~~~
然而,在很多情况下描述的内容是基于上下文环境的,比如说一个开关按钮的状态,或者在list中一片可选的数据项。在运行时编辑内容描述可以使用_setContentDescription()_方法,代码如下:
~~~
String contentDescription = "Select " + strValues[position];
label.setContentDescription(contentDescription);
~~~
将以上功能添加进您的代码是提高您应用可达性的最简单的方法。尝试着将那些有用的地方都加入内容描述,但同时要避免像web开发者那样将所有的元素都标注,那样会产生大量的无用信息。比如说,不要将应用图标的内容描述设置为_‘应用图标’_。这只会对用户的浏览产生干扰。
来试试吧!下载TalkBack(谷歌开发的一款可达性应用),在**Settings > Accessibility > TalkBack**将它开启。然后使用你的应用听听看TalkBack发出的语音提示。
### 设计焦点导航
你的应用除了支持触摸操作外,更应该支持其他的导航方式。很多Android设备不仅仅提供了触摸屏,还提供了其他的导航硬件比如说十字键、方向键、轨迹球等等。除此之外,最新的Android发行版本也支持蓝牙或USB的外接设备,比如键盘等等。
为了实现这种方式的导航,一切用户可以用来可导航的元素(_navigational elements_)都需要设置为focusable(_聚焦_),它可以在运行时通过_View.setFocusable()_方法来进行设定,或者也可以在XML布局文件中使用_android:focusable_来设置。
每个UI控件有四个属性,_android:nextFocusUp_,_android:nextFocusDown_,_android:nextFocusLeft_,_android:nextFocusRight_,用户在导航时可以利用这些属性来指定下一个焦点的位置。系统会自动根据布局的方向来确定导航的顺序,如果在您的应用中系统提供的方案并不合适,您可以用这些属性来进行自定义的修改。
比如说,下面就是一个关于按钮和标签的例子,他们都是可聚焦的(_focusable_),按向下键会将焦点从按钮移到文字上,按向上会重新将焦点移到按钮上。
~~~
<Button android:id="@+id/doSomething"
android:focusable="true"
android:nextFocusDown=”@id/label”
... />
<TextView android:id="@+id/label"
android:focusable=”true”
android:text="@string/labelText"
android:nextFocusUp=”@id/doSomething”
... />
~~~
证实您的应用运行正确的直观方法,最简单的方式就是在Android虚拟机里运行您的应用,然后使用虚拟器的方向键来在各个元素之间导航,使用OK按钮来代替触摸操作。
### 触发可达性事件
如果你在你的Android框架中使用了View组件,当你选中了一个View或者是焦点变化的时候,可达性事件(_AccessibilityEvent_)都会产生。这些事件会被传递到Accessibility Service中进行处理,实现一些辅助功能,如语音提示等。
如果你写了一个自定义的View,请确保它在合适的时候产生事件。使用_sendAccessibilityEvent(int)_函数可以产生可达性事件,其中的参数表示事件的类型。完整的可达性事件类型可查阅[AccessibilityEvent](http://developer.android.com/reference/android/view/accessibility/AccessibilityEvent.html)参考文档。
比如说,你拓展了一个图片的View,你希望在它聚焦的时候使用键盘打字可以在其中插入题注,这时候发送一个_TYPE_VIEW_TEXT_CHANGED_事件就非常合适,尽管它不是本身就构建在这个图片View中的。产生事件的代码如下:
~~~
public void onTextChanged(String before, String after) {
...
if (AccessibilityManager.getInstance(mContext).isEnabled()) {
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED);
}
...
}
~~~
### 测试你的程序
请确保您在添加可达性功能后测试它的有效性。为了测试内容描述可达性事件,请安装并启用一个Accessibility Service。比如说使用TalkBack,它是一个免费的开源的屏幕读取软件,可在Google Play上进行下载。Service启动后,请测试您应用中所有的功能,同时听听TalkBack的语音反馈。
同时,尝试着用一个方向控制器来控制你的应用,而非使用直接触摸的方式。你可以使用一个物理设备,比如十字键、轨迹球等。如果没有条件,可以使用android虚拟器,它提供了虚拟的按键控制。
在测试导航与反馈的同时,和在没有任何视觉提示的情况下,应该对你的应用大概是一个什么样子有所认识。出现问题就修复优化它们,最终就会开发出一个更易用可达的Android程序。
- 序言
- Android入门基础:从这里开始
- 建立第一个App
- 创建Android项目
- 执行Android程序
- 建立简单的用户界面
- 启动其他的Activity
- 添加ActionBar
- 建立ActionBar
- 添加Action按钮
- 自定义ActionBar的风格
- ActionBar的覆盖层叠
- 兼容不同的设备
- 适配不同的语言
- 适配不同的屏幕
- 适配不同的系统版本
- 管理Activity的生命周期
- 启动与销毁Activity
- 暂停与恢复Activity
- 停止与重启Activity
- 重新创建Activity
- 使用Fragment建立动态的UI
- 创建一个Fragment
- 建立灵活动态的UI
- Fragments之间的交互
- 数据保存
- 保存到Preference
- 保存到文件
- 保存到数据库
- 与其他应用的交互
- Intent的发送
- 接收Activity返回的结果
- Intent过滤
- Android分享操作
- 分享简单的数据
- 给其他App发送简单的数据
- 接收从其他App返回的数据
- 给ActionBar增加分享功能
- 分享文件
- 建立文件分享
- 分享文件
- 请求分享一个文件
- 获取文件信息
- 使用NFC分享文件
- 发送文件给其他设备
- 接收其他设备的文件
- Android多媒体
- 管理音频播放
- 控制音量与音频播放
- 管理音频焦点
- 兼容音频输出设备
- 拍照
- 简单的拍照
- 简单的录像
- 控制相机硬件
- 打印
- 打印照片
- 打印HTML文档
- 打印自定义文档
- Android图像与动画
- 高效显示Bitmap
- 高效加载大图
- 非UI线程处理Bitmap
- 缓存Bitmap
- 管理Bitmap的内存
- 在UI上显示Bitmap
- 使用OpenGL ES显示图像
- 建立OpenGL ES的环境
- 定义Shapes
- 绘制Shapes
- 运用投影与相机视图
- 添加移动
- 响应触摸事件
- 添加动画
- View间渐变
- 使用ViewPager实现屏幕侧滑
- 展示卡片翻转动画
- 缩放View
- 布局变更动画
- Android网络连接与云服务
- 无线连接设备
- 使得网络服务可发现
- 使用WiFi建立P2P连接
- 使用WiFi P2P服务
- 执行网络操作
- 连接到网络
- 管理网络
- 解析XML数据
- 高效下载
- 为网络访问更加高效而优化下载
- 最小化更新操作的影响
- 避免下载多余的数据
- 根据网络类型改变下载模式
- 云同步
- 使用备份API
- 使用Google Cloud Messaging
- 解决云同步的保存冲突
- 使用Sync Adapter传输数据
- 创建Stub授权器
- 创建Stub Content Provider
- 创建Sync Adpater
- 执行Sync Adpater
- 使用Volley执行网络数据传输
- 发送简单的网络请求
- 建立请求队列
- 创建标准的网络请求
- 实现自定义的网络请求
- Android联系人与位置信息
- Android联系人信息
- 获取联系人列表
- 获取联系人详情
- 使用Intents修改联系人信息
- 显示联系人头像
- Android位置信息
- 获取最后可知位置
- 获取位置更新
- 显示位置地址
- 创建和监视地理围栏
- Android可穿戴应用
- 赋予Notification可穿戴特性
- 创建Notification
- 在Notifcation中接收语音输入
- 为Notification添加显示页面
- 以Stack的方式显示Notifications
- 创建可穿戴的应用
- 创建并运行可穿戴应用
- 创建自定义的布局
- 添加语音功能
- 打包可穿戴应用
- 通过蓝牙进行调试
- 创建自定义的UI
- 定义Layouts
- 创建Cards
- 创建Lists
- 创建2D-Picker
- 创建确认界面
- 退出全屏的Activity
- 发送并同步数据
- 访问可穿戴数据层
- 同步数据单元
- 传输资源
- 发送与接收消息
- 处理数据层的事件
- Android TV应用
- 创建TV应用
- 创建TV应用的第一步
- 处理TV硬件部分
- 创建TV的布局文件
- 创建TV的导航栏
- 创建TV播放应用
- 创建目录浏览器
- 提供一个Card视图
- 创建详情页
- 显示正在播放卡片
- 帮助用户在TV上探索内容
- TV上的推荐内容
- 使得TV App能够被搜索
- 使用TV应用进行搜索
- 创建TV游戏应用
- 创建TV直播应用
- TV Apps Checklist
- Android企业级应用
- Ensuring Compatibility with Managed Profiles
- Implementing App Restrictions
- Building a Work Policy Controller
- Android交互设计
- 设计高效的导航
- 规划屏幕界面与他们之间的关系
- 为多种大小的屏幕进行规划
- 提供向下和横向导航
- 提供向上和历史导航
- 综合:设计样例 App
- 实现高效的导航
- 使用Tabs创建Swipe视图
- 创建抽屉导航
- 提供向上的导航
- 提供向后的导航
- 实现向下的导航
- 通知提示用户
- 建立Notification
- 当启动Activity时保留导航
- 更新Notification
- 使用BigView风格
- 显示Notification进度
- 增加搜索功能
- 建立搜索界面
- 保存并搜索数据
- 保持向下兼容
- 使得你的App内容可被Google搜索
- 为App内容开启深度链接
- 为索引指定App内容
- Android界面设计
- 为多屏幕设计
- 兼容不同的屏幕大小
- 兼容不同的屏幕密度
- 实现可适应的UI
- 创建自定义View
- 创建自定义的View类
- 实现自定义View的绘制
- 使得View可交互
- 优化自定义View
- 创建向后兼容的UI
- 抽象新的APIs
- 代理至新的APIs
- 使用旧的APIs实现新API的效果
- 使用版本敏感的组件
- 实现辅助功能
- 开发辅助程序
- 开发辅助服务
- 管理系统UI
- 淡化系统Bar
- 隐藏系统Bar
- 隐藏导航Bar
- 全屏沉浸式应用
- 响应UI可见性的变化
- 创建使用Material Design的应用
- 开始使用Material Design
- 使用Material的主题
- 创建Lists与Cards
- 定义Shadows与Clipping视图
- 使用Drawables
- 自定义动画
- 维护兼容性
- Android用户输入
- 使用触摸手势
- 检测常用的手势
- 跟踪手势移动
- Scroll手势动画
- 处理多触摸手势
- 拖拽与缩放
- 管理ViewGroup中的触摸事件
- 处理键盘输入
- 指定输入法类型
- 处理输入法可见性
- 兼容键盘导航
- 处理按键动作
- 兼容游戏控制器
- 处理控制器输入动作
- 支持不同的Android系统版本
- 支持多个控制器
- Android后台任务
- 在IntentService中执行后台任务
- 创建IntentService
- 发送工作任务到IntentService
- 报告后台任务执行状态
- 使用CursorLoader在后台加载数据
- 使用CursorLoader执行查询任务
- 处理查询的结果
- 管理设备的唤醒状态
- 保持设备的唤醒
- 制定重复定时的任务
- Android性能优化
- 管理应用的内存
- 代码性能优化建议
- 提升Layout的性能
- 优化layout的层级
- 使用include标签重用layouts
- 按需加载视图
- 使得ListView滑动顺畅
- 优化电池寿命
- 监测电量与充电状态
- 判断与监测Docking状态
- 判断与监测网络连接状态
- 根据需要操作Broadcast接受者
- 多线程操作
- 在一个线程中执行一段特定的代码
- 为多线程创建线程池
- 启动与停止线程池中的线程
- 与UI线程通信
- 避免出现程序无响应ANR
- JNI使用指南
- 优化多核处理器(SMP)下的Android程序
- Android安全与隐私
- Security Tips
- 使用HTTPS与SSL
- 为防止SSL漏洞而更新Security
- 使用设备管理条例增强安全性
- Android测试程序
- 测试你的Activity
- 建立测试环境
- 创建与执行测试用例
- 测试UI组件
- 创建单元测试
- 创建功能测试
- 術語表