Android TalkBack: Hint overwrites contentDescripti

2020-06-18 09:11发布

I have an EditText like below

<EditText
    android:id="@+id/extUsername"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:contentDescription="Username field"
    android:hint="Username" />

I want TalkBack to say "Username field" but it says "Username". It ignores contentDescription.

Do not tell me to remove hint or contentDescription. I need to use both.

Any advices will be appreciated.

6条回答
劫难
2楼-- · 2020-06-18 09:51

You need to add it in your string.xml file:

<string name="description">your desc goes here</string>
查看更多
再贱就再见
3楼-- · 2020-06-18 09:53

What you want to do is use LabelFor instead. LabelFor allows a visual label to be associated with an EditText box. You can make the visual label invisible if you'd like, so that it doesn't change your visual layout.

The down side to hints, is that they disappear after text is entered, making them pretty poor accessibility tools. If you're relying on hints for your Accessibility information, your app is not accessible.

Do something like this:

<TextView
     android:text="@string/yourEditTextDescription"
     android:labelFor="@+id/editTextField" />

<EditText android:id="@+id/editTextField"/>
查看更多
祖国的老花朵
4楼-- · 2020-06-18 09:57

Unfortunately, android:hint will always override android:contentDescription. You can create TextView which you will use only to set android:labelFor but from my experience TalkBack will then read both hint and labelFor.

The right way to add TextView which is only for labeling EditText for TalkBack :

    <TextView
         android:layout_width="0dp"
         android:layout_height="0dp"
         android:text="@string/yourDescription"
         android:labelFor="@+id/editText" />

    <EditText android:id="@+id/editText"/>

So one of the solutions is that you can check to see if TalkBack is on and change hint programmatically. You can check if TalkBack is on with:

  if(context.isScreenReaderOn){
    ...
}

And you create an inline function in Kotlin like :

fun Context.isScreenReaderOn():Boolean{
    val am = getSystemService(Context.ACCESSIBILITY_SERVICE) as AccessibilityManager
    if (am != null && am.isEnabled) {
        val serviceInfoList =
            am.getEnabledAccessibilityServiceList(AccessibilityServiceInfo.FEEDBACK_SPOKEN)
        if (!serviceInfoList.isEmpty())
            return true
    }
    return false}
查看更多
祖国的老花朵
5楼-- · 2020-06-18 10:04

You should extend EditText class with overriden TextView.getTextForAccessibility() method to get expected behaviour in the following way:

public CharSequence getTextForAccessibility() {
    CharSequence text = getText();
    if (TextUtils.isEmpty(text)) {
        text = getContentDescription();
    }
    return text;
}
查看更多
仙女界的扛把子
6楼-- · 2020-06-18 10:12

According to the official documentation, you shouldn't be setting android:contentDescription equal to anything. Instead, only use android:hint.

<EditText
    android:id="@+id/extUsername"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:hint="Username" />

"field" from your contentDescription should be removed, because TalkBack will announce it as "Username edit box"

查看更多
Animai°情兽
7楼-- · 2020-06-18 10:12

Note: For EditText fields, provide an android:hint attribute instead of a content description, to help users understand what content is expected when the text field is empty. When the field is filled, TalkBack reads the entered content from content description to help user, instead of the hint text.

For Hint -> android:hint

For TalkBack -> android:contentdescription

查看更多
登录 后发表回答