I have some TextView
s that I would like to announce as a header or a link in Talkback mode. Currently, it just announces the text inside the TextView
, but I would like it to say "Heading" afterwards, or "link" depending on the TextView
. For example, I would like Talkback mode to announce "Log in - heading" rather than just "Log in".
What I have tried so far is adding this in my Activity
's onCreate()
:
ViewCompat.setAccessibilityDelegate(v, new AccessibilityDelegateCompat() {
@Override
public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfoCompat info) {
super.onInitializeAccessibilityNodeInfo(host, info);
info.setHeading(true);
}
});
In Talkback mode, there is no change - it still just announces "log in".
What I notice is that this method, onInitializeAccessibilityNodeInfo
, is being called multiple times. When I step through in debugger, every time this method is triggered it shows that isHeading()
is false, then set to true.
Am I using this method incorrectly? Why is it called many times? Why is info.setHeading(true)
basically ignored?
How would I accomplish something similar, but with Talkback mode announcing "Label - Link" instead of header?
I have solved my issue!
The issue is that the TextView itself is not getting the focus. Instead, the container view, in this case the FrameLayout that wraps the TextView, was getting focus. That's why setting the TextView itself as a header was not appearing to work - the view around it was getting the focus.
So given the xml layout:
<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>
There are two solutions:
API 28+:
<FrameLayout
...
android:accessibilityHeading="true" >
or, in code, you can do the same thing as in my original question:
ViewCompat.setAccessibilityDelegate(v, new AccessibilityDelegateCompat() {
@Override
public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfoCompat info) {
super.onInitializeAccessibilityNodeInfo(host, info);
info.setHeading(true);
}
});
BUT you pass the container view in instead of the TextView.