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);
}