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。