我有一个自定义控件SeekBar
,其中我已覆盖onInitializeAccessibilityNodeInfo
,如下所示:
@Override
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
super.onInitializeAccessibilityNodeInfo(info);
info.setClassName(TextView.class.getName());
}
然后我将内容描述设置为"我的控件"对于这种控制,但当可访问性焦点出现在此控件上时,对讲仍然会说“我的控制,%x%"”。我不希望它说出进展,即" x%"。而不是我想要覆盖对讲文本,而不是宣布" x%......"它宣布我设置的自定义文本,例如"选择x值"。怎么做?
答案 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"
... />