Android TalkBack: подсказка перезаписывает содержимое описания
У меня есть EditText, как показано ниже
<EditText
android:id="@+id/extUsername"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="Username field"
android:hint="Username" />
Я хочу, чтобы TalkBack произнес "Поле имени пользователя", но там написано "Имя пользователя". Это игнорирует contentDescription.
Не говорите мне, чтобы удалить подсказку или contentDescription. Мне нужно использовать оба.
Любые советы будут оценены.
4 ответа
То, что вы хотите сделать, это использовать LabelFor вместо этого. LabelFor позволяет визуальной метке быть связанной с полем EditText. Вы можете сделать визуальную метку невидимой, если хотите, чтобы она не изменила ваш визуальный макет.
Обратной стороной подсказок является то, что они исчезают после ввода текста, что делает их довольно плохими инструментами доступности. Если вы полагаетесь на подсказки для информации о специальных возможностях, ваше приложение недоступно.
Сделайте что-то вроде этого:
<TextView
android:text="@string/yourEditTextDescription"
android:labelFor="@+id/editTextField" />
<EditText android:id="@+id/editTextField"/>
Согласно официальной документации, вы не должны устанавливать android:contentDescription
равно чему угодно. Вместо этого используйте только android:hint
,
<EditText
android:id="@+id/extUsername"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:hint="Username" />
"поле" от вашего contentDescription
должен быть удален, потому что TalkBack объявит его как "Поле ввода имени пользователя"
К сожалению, android:hint всегда отменяет android:contentDescription. Вы можете создать TextView, который вы будете использовать только для установки android:labelFor, но, по моему опыту, TalkBack затем прочитает и подсказку, и labelFor.
Правильный способ добавить TextView, который предназначен только для маркировки EditText для TalkBack:
<TextView
android:layout_width="0dp"
android:layout_height="0dp"
android:text="@string/yourDescription"
android:labelFor="@+id/editText" />
<EditText android:id="@+id/editText"/>
Таким образом, одним из решений является то, что вы можете проверить, включен ли TalkBack, и программно изменить подсказку. Проверить, включен ли TalkBack, можно с помощью:
if(context.isScreenReaderOn){
...
}
И вы создаете встроенную функцию в Kotlin, например:
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}
Примечание. Для полей EditText укажите атрибут android: hint вместо описания контента, чтобы помочь пользователям понять, какой контент ожидается, когда текстовое поле пусто. Когда поле заполнено, TalkBack считывает введенный контент из описания контента, чтобы помочь пользователю, вместо текста подсказки.
Для подсказки -> Android: подсказка
Для TalkBack -> Android: описание контента
Вы должны расширить класс EditText с помощью переопределенного метода TextView.getTextForAccessibility(), чтобы получить ожидаемое поведение следующим образом:
public CharSequence getTextForAccessibility() {
CharSequence text = getText();
if (TextUtils.isEmpty(text)) {
text = getContentDescription();
}
return text;
}
Вам нужно добавить его в ваш файл string.xml:
<string name="description">your desc goes here</string>