默认情况下,辅助功能服务将为 EditText 视图读出以下内容
- 如果 EditText 输入了一个值 = 它将读出该值
- 如果没有输入值=它将读出“提示”
我希望它在两种情况下都能读出完全不同的东西。
我的 xml 片段是
<EditText
android:id="@+id/my_edit_text"
android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_weight="1"
android:editable="false"
android:focusable="true"
android:hint="my hint text"/>
我必须支持 API 14 及更高版本。
我不想为这一个案例麻烦扩展 EditText,因此我使用的是 AccessibilityDelegate。
mEditTextView.setAccessibilityDelegate(accessibilityDelegate);
从文档中我了解到,在我的委托中,我只需要覆盖我想要更改行为的委托中的那些方法。所有其他方法将默认为 View 的实现。
http://developer.android.com/reference/android/view/View.AccessibilityDelegate.html http://developer.android.com/reference/android/view/View.html
“onPopulateAccessibilityEvent”的文档说:“让主机视图有机会使用其文本内容填充可访问性事件。 ”“dispatchPopulateAccessibilityEvent”的文档说:“首先将 AccessibilityEvent 分配给主机视图,然后再分配给它的子视图将他们的文本内容添加到事件中。 ”并且默认行为是为视图本身调用“onPopulateAccessibilityEvent”,然后在其所有子项上调用“dispatchPopulateAccessibilityEvent”
http://developer.android.com/guide/topics/ui/accessibility/apps.html
该文档在“onPopulateAccessibilityEvent”下说“*如果您对此事件的实现完全覆盖了输出文本,而不允许布局的其他部分修改其内容,则不要在您的代码中调用此方法的超级实现。”
因此,我的代表如下
View.AccessibilityDelegate accessibilityDelegate = new View.AccessibilityDelegate() {
@Override
public void onPopulateAccessibilityEvent(View v, AccessibilityEvent event) {
event.getText().add("Apples");
}
};
为什么当我使用键盘导航或使用屏幕点击 EditText 视图时,它仍在阅读“我的提示文本”而不是“Apples”?
如果我使用调试器,我会看到在设置事件文本之前,文本是空的,设置之后,它是“Apples”,但 TalkBack 仍会读出提示。
奇怪的是,如果我覆盖“onInitializeAccessibilityNodeInfo”并使用我想要的文本发送一个事件,那么这个想要的文本就会被读出(参见下面的代码片段)。但这对我来说似乎是错误的,因为“onInitializeAccessibilityNodeInfo”正在对 EditText 的事件做出反应,但随后只是引发了一个新事件。
@Override
public void onInitializeAccessibilityNodeInfo(View v, AccessibilityNodeInfo info){
super.onInitializeAccessibilityNodeInfo(v, info);
...
final AccessibilityEvent event = AccessibilityEvent.obtain(eventType);
event.getText().add("Pears");
event.setClassName(className);
event.setPackageName(packageName);
...
v.getParent().requestSendAccessibilityEvent(v, event);
}