Доступность для 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.

Другие вопросы по тегам