如何防止android对话发表seekbar进度

时间:2016-08-03 09:50:31

标签: android seekbar talkback

我有一个自定义控件SeekBar,其中我已覆盖onInitializeAccessibilityNodeInfo,如下所示:

@Override
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
    super.onInitializeAccessibilityNodeInfo(info);
    info.setClassName(TextView.class.getName());
}

然后我将内容描述设置为"我的控件"对于这种控制,但当可访问性焦点出现在此控件上时,对讲仍然会说“我的控制,%x%"”。我不希望它说出进展,即" x%"。而不是我想要覆盖对讲文本,而不是宣布" x%......"它宣布我设置的自定义文本,例如"选择x值"。怎么做?

3 个答案:

答案 0 :(得分:0)

我在C#中的Xamarin.Android中做了类似的事情,但是代码应该足够容易地移植回Java。另外,请记住,当控件突出显示时,这些更改将覆盖初始对讲。

首先在textView上跟踪值集:

textView.AccessibilityLiveRegion = AndroidViews.AccessibilityLiveRegion.Assertive;

然后我必须创建自己的自定义AccessibilityDelegate

public class CustomSeekbarDelegate : Android.Views.View.AccessibilityDelegate
{
    public override void OnInitializeAccessibilityEvent(AndroidViews.View host, AccessibilityEvent e)
    {
        //NOTE: Don't call base to prevent seekbar talkback percentage
    }
}

seekBar.SetAccessibilityDelegate(new CustomSeekbarDelegate());

首次突出显示时,可能有一种方法可以同时保留初始语音控件的可访问性,但是在线上并没有太多内容,这足以满足我们的需求。另外,我没有更多时间尝试使它也正常工作。

答案 1 :(得分:0)

感谢@ nick-peppers回答https://stackoverflow.com/a/58434362/2713403,我已经开始更好地理解AccessibilityDelegate的工作原理,因此我选择了一个搜索栏,因此提出了另一种解决方案。通过从OnInitializeAccessibilityEvent方法中删除超级调用,如果用户单击,则无法将选择保留在搜索栏上,因此我做到了这一点(在Android 11、10和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);
        }
    }
}

这样,我可以选择搜索栏,然后大声读出而没有百分比。不要忘记将事件SeekBar.OnSeekBarChangeListener附加到搜索栏,以在其更改时更新搜索栏文本。

答案 2 :(得分:-1)

有两种方法可以实现这一目标:

  • 以编程方式,您可以说:

    view.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO);
    
  • 在您的XML文件中,将重要性设置为" no"。

    <SeekBar
    android:importantForAccessibility="no"
    ... />