Android 无障碍服务包裹在定制 ViewGroup 内时的事件分发

阅读时长 5 分钟读完

无障碍服务是为了帮助使用者解决各种障碍,如视力、听力、语言、认知、运动等方面的问题。而在 Android 中,无障碍服务可以通过在一个应用中监听用户行为并根据修改应用的行为来改善其可访问性。举例来说,Android 中的 TalkBack 就是一个很好的无障碍服务,它允许视力有障碍的用户通过声音和语音输入来使用设备。

在应用中,尤其是应用的前端层中,我们经常会遇到自定义 ViewGroup 的需要。在这篇文章中,我们将关注如何在自定义 ViewGroup 中包裹无障碍服务时处理事件分发。

事件分发

当一个用户在 Android 设备上执行操作时,例如点击或滑动屏幕,该操作将通过事件分发层被处理。根据 Android 的官方文档,该层有三个关键组件。它们分别是:

  1. View:用户在其上执行操作的可视化组件。
  2. ViewGroup:View 的容器。
  3. Event:指示用户在 View 上执行的操作,例如点击或滑动。

在一个应用中,由于 View 可以被添加到其他 View 中,所以整个事件分发的过程也被称为事件分层层次结构。每当用户在某个 View 上执行操作时,该 View 将成为事件分发的根节点,并从该节点向下分发事件直到特定的 View 或 ViewGroup 捕获该事件。

最常见的示例之一是 button。当用户点击 button 上的按钮时,Android 系统将从 View 树的根节点开始分发事件。该事件将沿着 button 在 ViewGroup 中的路径传递,并在 button 上被捕获,从而引发相应的响应。

但当我们在自定义 ViewGroup 中添加无障碍服务时,事件分发可能会变得有些困难。在本文接下来的部分,我们将关注如何在自定义 ViewGroup 中处理事件分发。

解决方案

当我们在自定义 ViewGroup 中添加无障碍服务时,我们可能会遇到问题:无障碍服务不捕获它应该捕获的事件。这是因为无障碍服务重写了父类的事件分发方法,而父类情况下它正常工作。为了解决这个问题,我们需要在我们的自定义 ViewGroup 中实现事件分发方法。

为了说明这点,我们来看一个自定义 ViewGroup 的简单示例。该示例包含一个 TextView 和一个 Button。我们将在该 GroupView 中添加无障碍服务来让 TalkBack 能够读取 Button 的内容。

-- -------------------- ---- -------
------ ----- --------------- ------- -------------- -

    ------- -------- ---------
    ------- ------ -------

    ------ ----------------------- -------- -
        ------------- ------
    -

    ------ ----------------------- -------- ------------ ------ -
        ------------- ------ ---
    -

    ------ ----------------------- -------- ------------ ------ --- --------- -
        -------------- ------ ----------

        -------------- -------- - ---------------- ----------------------------------------------------------
        ---------------------------------------- ----- ------

        -------- - --------------------------------
        ------ - -----------------------------
    -

    ------ ---- -------------------- ----- -
        ---------------------
    -

    ---------
    ------ ------- ----------------------------------------------------- ------ -
        -- -- -------- ---- ------ ---
        -- --------------------- -- --------------------------------------------------- -
            --------------------------------------
        -

        ------ ------------------------------------------------
    -
-

在上面的示例中,我们使用 inflate 方法从 XML 文件中加载布局,并获取我们在自定义组件中添加的两个视图:TextView 和 Button。接下来,我们在 dispatchPopulateAccessibilityEvent 方法中重写事件分发逻辑,并将 TalkBack 所需的 Button 文字添加到其 AccessibilityEvent 对象的 getText() 方法中。

需要注意的是,在这个方法中,我们需要在设置 TalkBack 读取内容之前调用 super.dispatchPopulateAccessibilityEvent(event),以确保正常的事件分发对无障碍服务实际上是有效的。

像这样,在我们的自定义 ViewGroup 的 dispatchPopulateAccessibilityEvent 方法中添加更多逻辑来处理其他类型的事件也是可行的,例如许多自定义 View 和 ViewGroup 的 onClickListeners()。

结论

当我们在自定义 ViewGroup 中包裹无障碍服务时处理事件分发是一项非常实用的技能。通过正确实现我们自己的事件分发逻辑,我们可以确保无障碍服务能够在我们的自定义布局中正常工作。这对于那些需要更高级别的可访问性控制的移动应用程序开发人员尤其重要。

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/66fbb137447136260160b369

纠错
反馈