How to prevent android talkback to speak seekbar progress

前端 未结 3 1071
悲哀的现实
悲哀的现实 2021-01-19 10:51

I have a custom control extending SeekBar, in which I have overridden onInitializeAccessibilityNodeInfo as below:

@Override
public          


        
3条回答
  •  花落未央
    2021-01-19 11:41

    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.

提交回复
热议问题