我目前使用 . 检索活动窗口的根节点getRootInActiveWindow()
。之后,我执行广度优先搜索以获取所有节点的列表。
我的问题:如何遍历此节点列表以获得焦点顺序?该列表是否已根据节点的焦点顺序排序?是否有不同的方法来检索焦点顺序?
提前致谢。
我目前使用 . 检索活动窗口的根节点getRootInActiveWindow()
。之后,我执行广度优先搜索以获取所有节点的列表。
我的问题:如何遍历此节点列表以获得焦点顺序?该列表是否已根据节点的焦点顺序排序?是否有不同的方法来检索焦点顺序?
提前致谢。
最终,没有。您不能,并且关于此的可访问性 api 文档非常具有误导性。
有人可能会认为 AccessibilityNodeInfo 的“focusSearch(int direction)”功能是可行的方法。但是,最终它被打破了,如果你回到 Android Accessibility API 的内部,你最终会发现一个这样记录的函数:
在指定方向上搜索可以获取输入焦点的最近视图。
酷,正是我们想要的,对吧?稍等一下。这个函数调用一个函数
AccessibilityInteractionClient.getInstance().focusSearch(mConnectionId, mWindowId, mSourceNodeId, direction);
这个函数记录如下:
查找以可访问性为重点的 {@link android.view.accessibility.AccessibilityNodeInfo}。搜索在指定了 id 的窗口中执行,并从指定了可访问性 id 的节点开始。
令人失望的是,您还会发现此功能在这些工作(定向焦点搜索或定向可访问性焦点搜索)中都做得不好。
最终,当 TalkBack 中的元素由于元素的焦点而获得可访问性焦点时,它实际上是在响应来自操作系统的实际焦点事件,而不是 TalkBack 在输入焦点排序上所做的任何计算。
为了做到这一点,您基本上必须自己实现操作系统中用于 Tab 排序的整个逻辑,系统本身必须执行的信息较少,因为系统有真实的android.widget.View
对象要处理,而不是AccessibilityNodeInfo
信息有限的假对象. 任何你能想到的方法都将非常脆弱,并且不能保证与系统的实际操作一致。
focusable
您尝试对“输入可聚焦”(的属性)进行广度优先遍历的倾向AccessibilityNodeInfo
是一个非常合理的解决方案。问题是,真正的系统选项卡排序将是其中的一个子集,它忽略了诸如不同窗口上存在的元素之类的东西。
说真的,打开 TalkBack 设置屏幕,打开 TalkBack,连接硬件键盘,疯狂地使用 tab 键和 shift tab 键,惊叹于无法将注意力集中在“设置”按钮上。你的遍历函数会出错,因为“设置”按钮是focusable
,但不知何故,你不能把焦点放在那里。之所以深入研究我将省略的一些严重的 AOSP 废话,而且不,我不确定是否可以让 AccessibilityServices 获得可以防止这种极端情况出现在您的理论算法中的信息。
总而言之,广度优先遍历在理论上是可行的,但是会有大量的极端情况,而且我不确定 AccessibilityServices 是否可以使用正确处理每个极端情况的信息。此外,值得注意的是,由于这个特殊问题,如果您希望解决方案在 4.4、5.0 和 7.0+ 设备上是正确的,那么对于不同的操作系统版本,您必须对此计算有不同的变化。是的,那些角落案例会有所不同!(排队邪恶的笑声)。
我诚实的建议......放弃。