Доступность для Android: как изменить текст, читаемый вслух, для представления EditText
По умолчанию Accessibility Services будет считывать следующее для представления EditText
- Если EditText имеет введенное значение =, он будет считывать это значение
- Если не введено значение = это будет считывать "подсказку"
Я хочу, чтобы он прочитал что-то совершенно другое в обоих случаях.
Мой фрагмент XML
<EditText
android:id="@+id/my_edit_text"
android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_weight="1"
android:editable="false"
android:focusable="true"
android:hint="my hint text"/>
Я должен поддерживать API 14 и далее.
Я не хочу вдаваться в проблему расширения EditText для этого одного случая, поэтому я использую AccessibilityDelegate.
mEditTextView.setAccessibilityDelegate(accessibilityDelegate);
Из документации я понимаю, что в моем делегате мне нужно только переписать те методы в делегате, для которых я хотел бы изменить поведение. Все остальные методы по умолчанию будут реализованы в представлении.
http://developer.android.com/reference/android/view/View.AccessibilityDelegate.html http://developer.android.com/reference/android/view/View.html
Документ для "onPopulateAccessibilityEvent" говорит: " Дает возможность представлению хоста заполнить событие accessibility его текстовым содержимым. " Документ для "dispatchPopulateAccessibilityEvent" говорит: " Сначала отправляет AccessibilityEvent в представление хоста, а затем его потомкам для добавление их текстового содержимого к событию. "и что поведение по умолчанию заключается в вызове" onPopulateAccessibilityEvent "для самого представления, а затем" dispatchPopulateAccessibilityEvent "для всех его дочерних элементов.
http://developer.android.com/guide/topics/ui/accessibility/apps.html
Этот документ говорит в разделе "onPopulateAccessibilityEvent": "Если ваша реализация этого события полностью переопределяет выходной текст, не позволяя другим частям макета изменять его содержимое, то не вызывайте супер реализацию этого метода в вашем коде".
Поэтому мой делегат следующий
View.AccessibilityDelegate accessibilityDelegate = new View.AccessibilityDelegate() {
@Override
public void onPopulateAccessibilityEvent(View v, AccessibilityEvent event) {
event.getText().add("Apples");
}
};
Почему, когда я использую клавиатуру, чтобы перейти к экрану EditText или нажать на экран, он по-прежнему читает "текст моей подсказки", а не "Яблоки"?
Если я использую отладчик, я вижу, что до того, как я установлю текст события, текст будет пустым, и после того, как я его установлю, это "Яблоки", но TalkBack все еще считывает подсказку.
Странно, если я перезаписываю "onInitializeAccessibilityNodeInfo" и отправляю событие с моим желаемым текстом, тогда этот желаемый текст читается (см. Фрагмент кода ниже). Но это кажется мне неправильным, так как "onInitializeAccessibilityNodeInfo" реагирует на событие EditText, а затем просто вызывает новое.
@Override
public void onInitializeAccessibilityNodeInfo(View v, AccessibilityNodeInfo info){
super.onInitializeAccessibilityNodeInfo(v, info);
...
final AccessibilityEvent event = AccessibilityEvent.obtain(eventType);
event.getText().add("Pears");
event.setClassName(className);
event.setPackageName(packageName);
...
v.getParent().requestSendAccessibilityEvent(v, event);
}
2 ответа
Мы можем изменить текст, прочитанный вслух в представлении EditText, выполнив следующие действия:
View.AccessibilityDelegate accessibilityDelegate = new View.AccessibilityDelegate() {
@Override
public void onInitializeAccessibilityNodeInfo(View v, AccessibilityNodeInfo info) {
super.onInitializeAccessibilityNodeInfo(v, info);
info.setText("some customized text")
}
};
а затем установите этот делегат для представления EditText.
Это звучит очень похоже на проблему, с которой я сталкивался ранее: Android: Как убрать разговорный текст из AccessibilityEvents при расширении SeekBar?
Вы пытались (в качестве теста) очистить текст подсказки в onPopulateAccessibilityEvent
вместо того, чтобы просто добавить текст "Яблоки"? Кажется, я помню, что мои эмпирические результаты не соответствовали документации Android, особенно для ОС Android до API 14.