Android 辅助功能 - 无法将 TextView 声明为 Header 或 link
Android Accessibility - unable to announce TextViews as a Header or link
我有一些 TextView
想在对讲模式中作为 header 或 link 宣布。目前,它只宣布 TextView
内的文本,但我希望它之后说 "Heading",或 "link",具体取决于 TextView
。例如,我希望对讲模式宣布 "Log in - heading" 而不仅仅是 "Log in"。
到目前为止我尝试的是在我的 Activity
中添加这个 onCreate()
:
ViewCompat.setAccessibilityDelegate(v, new AccessibilityDelegateCompat() {
@Override
public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfoCompat info) {
super.onInitializeAccessibilityNodeInfo(host, info);
info.setHeading(true);
}
});
在对讲模式下,没有变化 - 它仍然只是宣布 "log in"。
我注意到此方法 onInitializeAccessibilityNodeInfo
被多次调用。当我在调试器中逐步执行时,每次触发此方法时,它都会显示 isHeading()
为 false,然后设置为 true。
我是不是用错了这个方法?为什么会被多次调用?为什么info.setHeading(true)
基本被忽略了?
我如何完成类似的事情,但使用对讲模式宣布 "Label - Link" 而不是 header?
试试这个:
ViewCompat.setAccessibilityDelegate(v, new AccessibilityDelegateCompat() {
@Override
public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfoCompat info) {
super.onInitializeAccessibilityNodeInfo(host, info);
info.setRoleDesccription("heading");
}
});
我的问题已经解决了!
问题是 TextView 本身没有获得焦点。相反,容器视图(在本例中为包装 TextView 的 FrameLayout)获得焦点。这就是为什么将 TextView 本身设置为 header 似乎不起作用的原因 - 它周围的视图正在获得焦点。
因此给定 xml 布局:
<FrameLayout
android:id="@+id/fl_login_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusableInTouchMode="true" >
...
<TextView
android:id="@+id/tv_login_header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/login_sign_in_to_your_account" />
</FrameLayout>
有两种解决方案:
API 28+:
<FrameLayout
...
android:accessibilityHeading="true" >
或者,在代码中,您可以按照我原来的问题做同样的事情:
ViewCompat.setAccessibilityDelegate(v, new AccessibilityDelegateCompat() {
@Override
public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfoCompat info) {
super.onInitializeAccessibilityNodeInfo(host, info);
info.setHeading(true);
}
});
但是您传递的是容器视图而不是 TextView。
我有一些 TextView
想在对讲模式中作为 header 或 link 宣布。目前,它只宣布 TextView
内的文本,但我希望它之后说 "Heading",或 "link",具体取决于 TextView
。例如,我希望对讲模式宣布 "Log in - heading" 而不仅仅是 "Log in"。
到目前为止我尝试的是在我的 Activity
中添加这个 onCreate()
:
ViewCompat.setAccessibilityDelegate(v, new AccessibilityDelegateCompat() {
@Override
public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfoCompat info) {
super.onInitializeAccessibilityNodeInfo(host, info);
info.setHeading(true);
}
});
在对讲模式下,没有变化 - 它仍然只是宣布 "log in"。
我注意到此方法 onInitializeAccessibilityNodeInfo
被多次调用。当我在调试器中逐步执行时,每次触发此方法时,它都会显示 isHeading()
为 false,然后设置为 true。
我是不是用错了这个方法?为什么会被多次调用?为什么info.setHeading(true)
基本被忽略了?
我如何完成类似的事情,但使用对讲模式宣布 "Label - Link" 而不是 header?
试试这个:
ViewCompat.setAccessibilityDelegate(v, new AccessibilityDelegateCompat() {
@Override
public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfoCompat info) {
super.onInitializeAccessibilityNodeInfo(host, info);
info.setRoleDesccription("heading");
}
});
我的问题已经解决了!
问题是 TextView 本身没有获得焦点。相反,容器视图(在本例中为包装 TextView 的 FrameLayout)获得焦点。这就是为什么将 TextView 本身设置为 header 似乎不起作用的原因 - 它周围的视图正在获得焦点。
因此给定 xml 布局:
<FrameLayout
android:id="@+id/fl_login_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusableInTouchMode="true" >
...
<TextView
android:id="@+id/tv_login_header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/login_sign_in_to_your_account" />
</FrameLayout>
有两种解决方案:
API 28+:
<FrameLayout
...
android:accessibilityHeading="true" >
或者,在代码中,您可以按照我原来的问题做同样的事情:
ViewCompat.setAccessibilityDelegate(v, new AccessibilityDelegateCompat() {
@Override
public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfoCompat info) {
super.onInitializeAccessibilityNodeInfo(host, info);
info.setHeading(true);
}
});
但是您传递的是容器视图而不是 TextView。