Android-将“话语提示”可访问性焦点设置为特定视图

问题描述 投票:24回答:2

启用“话语提示”后,有什么方法可以将可访问性焦点手册设置为特定视图?例如,当我的“活动”开始时,我希望“话语提示”自动关注某个按钮(视图周围的黄色框)并阅读其内容说明。

到目前为止我尝试过的:

    myButton.setFocusable(true);
    myButton.setFocusableInTouchMode(true);
    myButton.requestFocus();

requestFocus(),似乎只是请求输入焦点,与可访问性焦点无关。我也尝试过:

    myButton.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED);
    myButton.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
    myButton.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED);
    myButton.announceForAccessibility("accessibility test");
    myButton.performAccessibilityAction(64, null); // Equivalent to ACTION_ACCESSIBILITY_FOCUS

    AccessibilityManager manager = (AccessibilityManager) getSystemService(Context.ACCESSIBILITY_SERVICE);
    if (manager.isEnabled()) {
        AccessibilityEvent e = AccessibilityEvent.obtain();
        e.setSource(myButton);
        e.setEventType(AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED);
        e.setClassName(getClass().getName());
        e.setPackageName(getPackageName());
        e.getText().add("another accessibility test");
        manager.sendAccessibilityEvent(e);
    }

这似乎都不起作用。

android accessibility talkback
2个回答
40
投票

免责声明:强迫活动负荷始终放在顶部栏之外的任何位置(好吧,几乎永远不应该说),但实际上,只是不要这样做。这分别违反了有关可预测的导航和上下文更改的各种WCAG 2.0法规,包括3.2.1和3.2.3。通过执行此操作,您实际上可能使您的应用无法访问。

http://www.w3.org/TR/WCAG20/#consistent-behavior

END免责声明。

您正在使用正确的函数调用。您需要做的就是:

myButton.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);

问题很可能是您尝试执行此操作的时间。对讲会在活动周期的稍后阶段将其自身附加到您的活动上。以下解决方案说明了此问题,老实说,我不确定有更好的方法来解决此问题。我尝试了onPostResume,这是Android OS调用的关于活动加载的最后一个回调,但仍然需要延迟添加。

@Override
protected void onPostResume() {
    super.onPostResume();

    Log.wtf(this.getClass().getSimpleName(), "onPostResume");

    Runnable task = new Runnable() {

        @Override
        public void run() {
            Button theButton = (Button)WelcomeScreen.this.findViewById(R.id.idButton);
            theButton.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
        }
    };

    final ScheduledExecutorService worker = Executors.newSingleThreadScheduledExecutor();

    worker.schedule(task, 5, TimeUnit.SECONDS);

}

您也许可以创建自定义视图。视图中的回调可能会提供您所需的逻辑,而不会出现争用条件!如果有时间,我可能会在以后再研究。


0
投票

我有同样的问题,因为为了保持一致的导航,我们希望选择新打开的页面的标题。问题是屏幕阅读器正在选择页面左上方的第一个标题按钮,而不是标题。

我在整个视图中都有一个myRootView变量,在标题文本视图中有一个myTitleView变量。

ChrisCM为使可访问性集中在正确视图上而提出的解决方案绝对帮助了我:

myTitleView.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);

但是,我仍然遇到这样的问题,因为屏幕阅读器尚未准备好,因此在应用启动时调用此代码没有任何效果,而我提出的等待5整秒的“等待对讲可用的解决方案”并不是我想要的。这样做是因为到那时,用户可能已经在使用该界面,并且自动聚焦会打断他们的选择。

[我注意到在打开应用程序时,左上角的标题按钮是通过可访问性系统地选择的,所以我编写了一个类来侦听该选择并随后触发我自己的选择。

这里是所讨论课程的代码:

import android.view.View;
import android.view.View.AccessibilityDelegate;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityEvent;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

public abstract class OnFirstAccessibilityFocusRunner extends AccessibilityDelegate implements Runnable {
    @NonNull
    private final View rootView;
    private boolean hasAlreadyRun = false;

    public OnFirstAccessibilityFocusRunner(@NonNull final View _rootView) {
        rootView = _rootView;
        init();
    }

    private void init() {
        rootView.setAccessibilityDelegate(this);
    }

    @Override
    public boolean onRequestSendAccessibilityEvent(@Nullable final ViewGroup host, @Nullable final View child,
        @Nullable final AccessibilityEvent event) {
        if (!hasAlreadyRun//
            && event != null//
            && event.getEventType() == AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED//
        ) {
            hasAlreadyRun = true;
            rootView.setAccessibilityDelegate(null);
            run();
        }
        return super.onRequestSendAccessibilityEvent(host, child, event);
    }
}

然后,我使用这样的代码(例如,在Activity的onPostResume方法中:]]

@Override
protected void onPostResume() {
    new OnFirstAccessibilityFocusRunner(myRootView) {
        @Override
        public void run() {
            myTitleView.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
        }
    };
}

我花了几个小时才弄清楚如何立即将焦点对准正确的视图,希望对其他人也有帮助!

© www.soinside.com 2019 - 2024. All rights reserved.