I have a custom control extending SeekBar
, in which I have overridden onInitializeAccessibilityNodeInfo
as below:
@Override
public
Thanks to @nick-peppers answer https://stackoverflow.com/a/58434362/2713403 I had started to understand better how AccessibilityDelegate works, so I made a different solution because I wanted to select the seekbar. By removing the super call from OnInitializeAccessibilityEvent method, it wasn't possible to keep the selection on the seek bar if the user clicks, so I made this (Tested on Android 11, 10 and 9)
...
seekbar.setAccessibilityDelegate(new customSeekBarDelegate());
...
/**
* Create a custom delegate to modify what Talkback is going to read out loud
*/
private class customSeekBarDelegate extends View.AccessibilityDelegate
{
/**
* If the selected view is the slider, populate the text to read by talkback.
* On Android 10 and 9, the view got selected from the beginning without touch the slider,
* so the TYPE_VIEW_SELECTED event is controlled.
* The text should be overwritten to trigger what Talkback do need to read.
*
* @param host The view selected
* @param event The event to initialise
*/
@Override public void onInitializeAccessibilityEvent(View host, AccessibilityEvent event)
{
super.onInitializeAccessibilityEvent(host, event);
if (event.getEventType() != AccessibilityEvent.TYPE_VIEW_SELECTED)
{
seekbarText.setText(seekbarText.getText());
}
}
/**
* Send all accessibility events except the focused accessibility event
* because it reads the percentage, so it needs to be changed to no focused to read
* the sliderText.
*
* @param host the view selected
* @param eventType The accessibility event to send
*/
@Override public void sendAccessibilityEvent(View host, int eventType)
{
if (eventType == AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED)
{
eventType = AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED;
}
super.sendAccessibilityEvent(host, eventType);
}
/**
* If the slider changes, it won't send the AccessibilityEvent TYPE_WINDOW_CONTENT_CHANGED
* because it reads the percentages, so in that way it will read the sliderText.
* On Android 10 and 9, the view got selected when it changes, so the TYPE_VIEW_SELECTED
* event is controlled.
*
* @param host the view selected
* @param event the accessibility event to send
*/
@Override public void sendAccessibilityEventUnchecked(View host, AccessibilityEvent event)
{
if (event.getEventType() != AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED
&& event.getEventType() != AccessibilityEvent.TYPE_VIEW_SELECTED)
{
super.sendAccessibilityEventUnchecked(host, event);
}
}
}
So in that way, I could have selected the seekbar, and read out loud without percentages. Don't forguet to attach the event SeekBar.OnSeekBarChangeListener to the seekbar to update the seekbar text when it changes.