修改无障碍焦点顺序

26

是否有可能更改可访问性焦点顺序?例如,如果我有三个并排的视图,它们的ID分别为view1、view2和view3,是否有简单的方法使可访问性焦点从view1向右滑动时转到view3?

以下是我尝试过的:

我在线性布局中尝试了以下内容。

<ImageView
    android:layout_width="30dp"
    android:layout_height="30dp"
    android:id="@+id/imageView"
    android:focusable="true"
    android:nextFocusUp="@+id/imageView3"
    android:nextFocusDown="@+id/imageView3"
    android:nextFocusRight="@+id/imageView3"
    android:nextFocusLeft="@+id/imageView3"
    android:nextFocusForward="@+id/imageView3"
    android:src="@drawable/ic_launcher"/>

<ImageView
    android:layout_width="30dp"
    android:layout_height="30dp"
    android:id="@+id/imageView2"
    android:focusable="true"
    android:src="@drawable/ic_launcher"/>

<ImageView
    android:layout_width="30dp"
    android:layout_height="30dp"
    android:id="@+id/imageView3"
    android:focusable="true"
    android:nextFocusUp="@+id/imageView2"
    android:nextFocusDown="@+id/imageView2"
    android:nextFocusRight="@+id/imageView2"
    android:nextFocusLeft="@+id/imageView2"
    android:nextFocusForward="@+id/imageView2"
    android:src="@drawable/ic_launcher"/>

然后,我启动这个应用并将可访问性焦点放在第一个imageView上。当向右滑动以移动到下一项时,我期望它会将可访问性焦点移动到imageView3,但实际上它去了imageView2。


3
从技术上讲,如果您设置了AccessibilityDelegate并手动添加子节点,则可以明确指定遍历顺序,但这会导致其他问题,并且不能保证在TalkBack更改如何处理焦点遍历时有效。这仍然是无障碍框架的一个待解决的功能需求。 - alanv
@alanv 你有那个突出的功能请求链接吗?我很想关注它的进展。更改遍历顺序对于新的浮动操作按钮尤其有帮助。如果它悬浮在自动加载列表上,用户可能永远无法通过向右滑动找到它。(请参见收件箱中的此问题示例) - Kio Krofovitch
没关系,看起来它只是在API 22中添加的!已经回答了原始问题。 - Kio Krofovitch
1个回答

49

对于minSdkVersion >= 22的应用程序,您可以直接在XML中使用android:accessibilityTraversalAfter设置屏幕阅读器的遍历顺序:

<ImageView
    android:id="@+id/imageView"
    android:layout_width="30dp"
    android:layout_height="30dp"
    android:src="@drawable/ic_launcher" />

<ImageView
    android:id="@+id/imageView2"
    android:layout_width="30dp"
    android:accessibilityTraversalAfter="@id/imageView3"
    android:layout_height="30dp"
    android:src="@drawable/ic_launcher" />

<ImageView
    android:id="@+id/imageView3"
    android:layout_width="30dp"
    android:layout_height="30dp"
    android:src="@drawable/ic_launcher" />

对于支持较低 API 级别的应用程序,可以使用 ViewCompat 编程方式设置遍历顺序:

ViewCompat.setAccessibilityDelegate(imageView2, object : AccessibilityDelegateCompat() {
    override fun onInitializeAccessibilityNodeInfo(host: View?, info: AccessibilityNodeInfoCompat?) {
        info?.setTraversalAfter(imageView3)
        super.onInitializeAccessibilityNodeInfo(host, info)
    }
})

请谨记,屏幕阅读器用户依赖于导航的一致性,因此更改焦点顺序是一种反模式,应避免。


11
对于版本小于22,有没有解决方案? - vtlinh
3
我认为@vtlinh的问题比原来的问题更重要。22太新了,有人知道旧版本的解决方案吗? - Carlos
3
我在使用这个在RecyclerView项目中时遇到问题。在遍历当前项后,它会跳到列表的下一项。 - azizbekian
3
似乎有一个兼容类用于此:AccessibilityNodeInfoCompat。它包含了setTraversalBeforesetTraversalAfter方法。 - user3829751
3
尝试这个的任何人,它只适用于>=22。小于22没有解决方案。 - Saurabh
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接