10.1 易于访问
许多Android用户有残疾,需要给他们提供不同的方式来与Android设备进行交互。
android提供了一个accessibility层,帮助用户更容易的浏览android设备,这又是让你软件更强大的一个细节方面,让我们好好学习吧
10.1.1 允许用一个定向控制器导航
许多android 设备都具备某种定向控制器,如:
- 一个用户能在任何方向移动的轨迹球。
- 一个允许用户在四个方向导航的d-pad。
- 一个类似箭头的按键和OK按钮,相当于点击一个轨迹球或d-pad 。
通过操作这些控制器,用户可以不同使用触摸屏也能导航到其他界面。关于不使用触摸屏而控制导航的方法,最好引入焦点概念。
Android提供了几个API,让你控制一个部件是否有焦点,甚至要求一个widget 获得焦点。这些方法包括:
setFocusable()
isFocusable()
requestFocus()
这是代码中的方法,如果在xml布局文件中,我们可以使用 android:focusable
为"true"
10.1.1.1 控制焦点顺序
当用户想要使用定向控制时,焦点从一个View传递到另一个View,它由焦点的顺序决定。这个焦点运转的顺序是基于一个规则的,这个规则就是它会根据一个特定的方向找最近的邻居。有时候你可能不想要使用默认的焦点传递顺序,你想自己定义。下面就让我们看看XML中有哪些方法定于焦点顺序(下面方法如字面意思就不详述了)
-
android:nextFocusDown
android:nextFocusLeft
-
android:nextFocusRight
-
android:nextFocusUp
例如,下面有一个Xml布局文件,TextView上包含一个焦点。当TextView位于EditText的右边,这样你按下down arrow 就能吧焦点传递到EditText:
"horizontal"
... >
"@+id/edit"
android:nextFocusDown=”@+id/text”
... />
"@+id/text"
android:focusable=”true”
android:text="Hello, I am a focusable TextView"
android:nextFocusUp=”@id/edit”
... />
当然我们还可以在运行时修改焦点顺序,例如使用View类的setNextFocusDownId()
和setNextFocusRightId()
.
10.1.1.2 用一个定向控制器点击
在大多数设备中,使用定向控制器点击一个View会发送一个KeyEvent,并且键码为KEYCODE_DPAD_CENTER
到当前获得焦点的View中。当你在触摸屏上触摸View时确保这个事件是一样的效
果。所有标准android View会提前适当的处理KEYCODE_DPAD_CENTER
。如果可能的话,建议吧KEYCODE_ENTER
和KEYCODE_DPAD_CENTER
看成一致的。
10.1.2 在你的输入部件设置一个标签
许多输入widgets会有一个提示,让用户知道这个是用来输入什么的。例如 一个记事本App可能使用带“+”号的图片来提示用户点击它来添加一个新的记录。或者一个EditText附近有一个
View,来提示它的用途。当然对于视力有问题的用户,这种提示是没什么用的。关于这种输入部件,要提供文本提示信息的话,你可以使用android:contentDescription
属性。或者使用障碍
语音工具,吧这个属性的描述朗读给用户很多View中都有这个android:contentDescription
到时候用的时候在查即可,下面是一个ImageButton使用这个属性的例子。
<ImageButton
android:id=”@+id/add_entry_button”
android:src=”@drawable/plus”
android:contentDescription=”Add note”/>
10.1.3 从自定义组件发送Accessibility Events
如果您的应用程序,您需要创建一个自定义的视图组件,你可能需要做一些额外的工作,以确保您的View是可访问。具体来说,你应该确保你的View实现AccessibilityEventSource
接口并在
适当的时间发送AccessibilityEvent,因为每个
AccessibilityEvent
包含关于View状态的重要信息。
在用户界面上,当有重要的事件发生就发送一个事件。目前有五种访问事件,View应该发送此事件到系统用来与用户交互:
-
TYPE_VIEW_CLICKED
- 表明用户点击一个View(例如,用户选择一个按钮)
-
TYPE_VIEW_LONG_CLICKED
- 表明用户正在对一个View长按
-
TYPE_VIEW_SELECTED
-
表明用户在view中选择一个item。通常适用于一个
AdapterView
中 -
TYPE_VIEW_FOCUSED
- 表明用户移动焦点到view
-
TYPE_VIEW_TEXT_CHANGED
- 表明View的文本或内容被改变了
基本的View类实现了 AccessibilityEventSource
并在适当的时候发送这些事件。你自定义的View应该继承Android中的View类。
根据我们自定义View的特性,我们可以使用sendAccessibilityEvent()
来发送特定的事件
@Override
public boolean onKeyUp (int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
mCurrentValue--;
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED);
return true;
}
...
}
每个AccessibilityEvent有一组所需的属性描述当前状态的View。这些属性包括像View的类名,文本和选中状态。每个事件类型所需要的具体属性描述在AccessibilityEvent文件。
View中还有一个dispatchPopulateAccessibilityEvent()方法,当AccessibilityEvent被发送前用来改变AccessibilityEvent对象。
以上面的滑块为例,View应该增加滑块的当前值的事件文本:
@Override
public boolean dispatchPopulateAccessibilityEvent(final AccessibilityEvent event) {
super.dispatchPopulateAccessibilityEvent(event);
if (!isShown()) {
return false;
}
CharSequence text = String.valueOf(mCurrentValue);
if (text.length() > AccessibilityEvent.MAX_TEXT_LENGTH) {
text = text.subSequence(0, AccessiblityEvent.MAX_TEXT_LENGTH);
}
event.getText().add(text);
return true;
}