当前位置: 首页 > 知识库问答 >
问题:

Android-将对讲可访问性焦点设置为特定视图

李景天
2023-03-14

启用对讲后,是否有办法将辅助功能焦点手册设置为特定视图?例如,当我的活动开始时,我希望TalkBack自动聚焦于某个按钮(视图周围的黄色框)并读取其内容描述。

到目前为止,我所尝试的:

    myButton.setFocusable(true);
    myButton.setFocusableInTouchMode(true);
    myButton.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);
    }

这些似乎都不起作用。

共有3个答案

卞轶
2023-03-14

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

我有一个myRootView变量用于整个视图,一个myTitleView变量用于标题文本视图。

ChrisCM为使无障碍性集中在正确的视图上而提出的解决方案无疑帮助了我:

myTitleView.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);

然而,我仍然有一个问题,即在应用程序启动时调用此代码没有任何效果,因为屏幕阅读器还没有准备好,而为“等待对讲可用”而提出的等待5秒的解决方案并不是我想做的,因为到那时,用户可能已经在使用该界面,他们的选择将被自动聚焦中断。

我注意到,在appopen上,左上角的标题按钮是由可访问性系统地选择的,所以我编写了一个类来侦听该选择并在之后触发我自己的选择。

以下是相关课程的代码:

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);
    }
}

然后我使用这样的代码(例如在活动的onPostResume方法中):

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

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

姬翰林
2023-03-14

最近我也有同样的问题。我创建了一个Android扩展函数来聚焦一个视图,而这个视图不像其他解决方案那样使用postDelayed来聚焦;

sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED)

但我有另一个场景,它不起作用。然而,我用它来解决这个问题:

fun View.accessibilityFocus(): View {
    this.performAccessibilityAction(AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null)
    this.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED)
    return this
}
宋烨烁
2023-03-14

免责声明:强制将注意力集中在活动负载上,而不是放在最上面的栏上,这是永远的(好吧,永远都不应该说),但实际上,就是不要这样做。这违反了WCAG 2.0的所有规定,包括3.2.1和3.2.3,分别涉及可预测的导航和上下文更改。这样做很可能会让你的应用程序更难访问。

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

结束免责声明。

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

myButton.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);

问题更可能出现在您尝试这样做的时候。对讲会在活动周期稍晚的时候连接到您的活动中。下面的解决方案说明了这个问题,老实说,我不确定有没有更好的方法来解决这个问题。我尝试了关于活动加载的PostResume,这是Android操作系统调用的最后一次回调,但我仍然不得不添加延迟。

@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);

}

您可以创建自定义视图。视图中的回调可能会提供执行此操作所需的逻辑,而无竞争条件!如果我有时间的话,我以后可能会进一步调查。

 类似资料:
  • 所以,我有一个用Java编写的Android应用程序。我希望能够在可访问性选项中为视障人士使用对讲。当用户在活动中滑动时,对讲“聚焦”在各种组件上,我希望能够知道这一点: 1)如何知道它是否“聚焦”在某个组件上(例如,textview)? 2) 当它“聚焦”在某个组件上时,如何中断它播放我自己的音频文件,然后返回,让对讲机再次接管? 提前感谢您! ----编辑 为了更清楚一点,以防你不熟悉对讲..

  • 我在文本视图下方有一个水平回收器视图(最近的项目在最右边的位置,最古老的项目在最左边的位置)。一旦辅助功能控件到达文本视图,在向右滑动时,它会聚焦在回收器视图的最左边的项目(即第一个项目)。有没有办法我们可以将默认焦点设置为最右边的项目。

  • 我有一个页面,用户需要输入他们的电子邮件,然后点击底部的按钮进行确认。确认电子邮件时,屏幕上会显示一个进度对话框。当在编辑文本中输入无效电子邮件时,就像只输入字母“a”一样,编辑文本下方会以文本视图的形式显示一条错误消息。我正在努力让这个页面更容易访问。 我的预期方法是,当错误文本出现时,让对讲模式聚焦在错误文本上。然而,这并不是很有效。相反,当解除“进程”对话框覆盖时,屏幕上的任何内容都不会通过

  • 我有这个应用程序与WebView显示HTML内容。 在我做了一些相当大的更改之后,对讲的可访问性出现了一些“问题”,特别是文本到语音和触摸探索,仅在4.4设备上(不在5.0上)。 触摸一段(段落)文本有时会起作用,但有时会产生点击声,没有输出,文本也不会像应该的那样用选择矩形突出显示。 在5.0上,一切都很好:触摸一段文本会在其周围绘制一个选择,文本就会被说出。 我知道4.4上的回归与我的一些更改

  • 我目前正努力用更多的发声来创建。背景是: 我想为用户在左右选项卡上添加“未选择选项卡[选项卡名称],单击两次以选择”和“已选择选项卡[选项卡名称]”到中间位置 我还想在单击选项卡时添加一个发声,以警告用户其内容已更改,并告诉聚焦中心选项卡 通过重写所有需要的类(例如:,,),并直接在选项卡上添加右侧的,我已经部分成功地完成了这项工作。它运行得相当好,但我不满意。这些类的维护需要针对Android主

  • 我已经为我的应用程序编写了自己的。在内部,它使用为通过我的应用导航的用户提供语音反馈。当打开和时,我从我的应用程序中获得口头反馈,然后是TalkBack的反馈。 有什么方法可以停止TalkBack为我的应用程序,因为我拥有我的应用程序的可访问性服务?