Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I give an additional label for a TextView that's only announced by TalkBack, not shown visually?

Say I have a list of items, and one of the views in each item is a message, in a simple TextView, that is populated in code (dynamic data from a backend service).

<TextView
    android:id="@+id/message" 
    style="@style/DefaultText"                    
    />    

Visually it doesn't need a label; the list item layout is pretty clear. But listening to how TalkBack reads the screen, I think it would be beneficial to have a "label" or description for it. So that TalkBack would read something like:

Message: [the actual dynamic message content]

My question is: is it possible to add a label/description for a TextView that, firstly, does not replace the TextView content, but is read along with it, and secondly, only affects TalkBack (not the visual presentation)?

What I tried:

  • contentDescription for the TextView. Doesn't work: if set, the actual content is not announced, only the contentDescription. Hmm, maybe if I'd set this in code with the description prepended to the actual content... but is there no easier way?
  • Separate TextView with labelFor pointing to @+id/message. The problem is that it's also shown visually and screws up the design. If I make it not visible, one way or other, it seems TalkBack won't read it either.
like image 404
Jonik Avatar asked Nov 27 '22 02:11

Jonik


1 Answers

Alright, I found two solutions! As mentioned in the question, I'd rather have avoided doing it in code, but it seems for optimal results that's the way to go.

Use android:hint in XML

The most simple way is to set android:hint="Message" for the TextView. TalkBack reads it after the actual text:

[the actual dynamic message content] Message

For my needs, with the message being optional, this has some drawbacks: the hint is announced even if the TextView has no actual content (I'd prefer to omit it then), and in that case it's also shown visually (not what I want). Also, I'd prefer TalkBack to read the hint before the actual text.

Set contentDescription programmatically

Not as simple, but not complicated either, and you have complete control over what TalkBack says.

In my case, preferring to omit the description if message is missing and having it read before the message content, I'd do something like this in the code that populates the list items:

textView.setText(message);
if (!TextUtils.isEmpty(message)) {        
    textView.setContentDescription(
        context.getString(R.string.message_desc, message));
}

With resource:

<string name="message_desc">Message: %s</string>
like image 182
Jonik Avatar answered Dec 04 '22 20:12

Jonik