Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Acccessibility: How do I change the text read out loud for an EditText View

By default, the Accessibility Services will read out the following for an EditText view

  • If the EditText has a value entered = it will read out that value
  • If there is not value entered = it will read out the "hint"

I want it to read out something completely different in both cases.

My xml snippet is

<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"/>

I have to support API 14 and onwards.

I do not want to go to the trouble of extending EditText for this one single case, therefore I am using am AccessibilityDelegate.

mEditTextView.setAccessibilityDelegate(accessibilityDelegate);

From the documentation I understand that in my delegate I only have to overwrite those methods in the delegate for which I would like to change the behaviour. All other methods will default to the View's implementation.

http://developer.android.com/reference/android/view/View.AccessibilityDelegate.html http://developer.android.com/reference/android/view/View.html

The doc for "onPopulateAccessibilityEvent" says : "Gives a chance to the host View to populate the accessibility event with its text content." The doc for "dispatchPopulateAccessibilityEvent" says : "Dispatches an AccessibilityEvent to the host View first and then to its children for adding their text content to the event." and that the default behaviour is to call "onPopulateAccessibilityEvent" for the view itself and then "dispatchPopulateAccessibilityEvent" on all its children

http://developer.android.com/guide/topics/ui/accessibility/apps.html

This doc says under "onPopulateAccessibilityEvent" "*If your implementation of this event completely overrides the output text without allowing other parts of your layout to modify its content, then do not call the super implementation of this method in your code."

Therefore my delegate is the following

View.AccessibilityDelegate accessibilityDelegate = new View.AccessibilityDelegate() {
    @Override
    public void onPopulateAccessibilityEvent(View v, AccessibilityEvent event) {
        event.getText().add("Apples");
    }

};

Why when I use the keyboard to navigate to or use the screen to tap on the EditText view it is still reading "my hint text" and not "Apples"?

If I use a debugger, I see that before I set the event text, the text is empty and after I set it, it is "Apples" yet the TalkBack still reads out the hint.


Weirdly if I overwrite "onInitializeAccessibilityNodeInfo" and send an event with my desired text, then this desired text gets read out (see code snippet below). But this seems wrong to me as the "onInitializeAccessibilityNodeInfo" is reacting to the EditText's event but then just raising a new one.

@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);  
}
like image 508
se22as Avatar asked Sep 03 '14 09:09

se22as


People also ask

How do you change text from read only on android?

The most reliable way to do this is using UI. setReadOnly(myEditText, true) from this library. There are a few properties that have to be set, which you can check out in the source code.

Is text view editable?

Edit: The TextView 's editable param does make it editable (with some restrictions). If you set android:editable="true" you can access the TextView via the D-pad, or you could add android:focusableInTouchMode="true" to be able to gain focus on touch.

What is the difference between edit text and TextView android?

EditText is used for user input. TextView is used to display text and is not editable by the user. TextView can be updated programatically at any time.

What is editable text in android?

Android App Development for Beginners A EditText is an overlay over TextView that configures itself to be editable. It is the predefined subclass of TextView that includes rich editing capabilities.


2 Answers

We can change the text read out loud of EditText view by doing the following:

View.AccessibilityDelegate accessibilityDelegate = new View.AccessibilityDelegate() {
    @Override
    public void onInitializeAccessibilityNodeInfo(View v, AccessibilityNodeInfo info) {
        super.onInitializeAccessibilityNodeInfo(v, info);
        info.setText("some customized text")
    }  
};

and then set this delegate to the EditText View.

like image 71
Binary Baba Avatar answered Sep 22 '22 16:09

Binary Baba


This sounds very similar to a problem I previously encountered: Android: How to eliminate spoken text from AccessibilityEvents when extending SeekBar?

Have you tried (as a test) clearing the hint text in onPopulateAccessibilityEvent, rather than just adding the 'Apples' text? I seem to remember that my empirical results did not match the Android documentation, particularly for Android OS prior to API 14.

like image 33
AwayTeam Avatar answered Sep 20 '22 16:09

AwayTeam