Facebook出品的Android声明式开源新框架Litho文档翻译-无障碍环境

欢迎转载,转载请标明出处.
英文原文文档地址: Litho-doc

兼容性

无障碍环境


内容描述


所有的Component都默认支持内容描述.这意味着所有的布局builder都拥有一个CharSequence类型的prop叫做contentDescription.

在任何component上设置内容描述都非常的简单:

1
2
3
4
5
Image.create(c)
.imageRes(R.drawable.some_image)
.withLayout()
.contentDescription("This is an image")
.build())

在这里设置的内容描述与在Android view上设置的内容描述拥有同等的效果.


自定义


在Mount Spec可以通过实现一个@OnPopulateAccessibilityNode方法来实现自定义的无障碍支持.这个方法接受一个AccessibilityNodeInfoCompat参数,也接受任何在其他spec方法中指定的prop参数.

举例来说,Text的无障碍功能是使用下列方法指定的:

1
2
3
4
5
6
@OnPopulateAccessibilityNode
static void onPopulateAccessibilityNode(
AccessibilityNodeInfoCompat accessibilityNode,
@Prop CharSequence text) {
accessibilityNode.setText(text);
}

这仅适用于挂载drawable的Component,因为如果Component挂载一个view,则无障碍支持就是内置的了.


额外的无障碍节点


如果是在更复杂的需要暴露更多额外的node给无障碍框架的mount spec中,你就必须使用以下的注释实现3个额外的方法:

  • GetExtraAccessibilityNodesCount:返回Component暴露出的外的无障碍节点的个数.
  • OnpopulateExtraAccessibilityNode:使用给定的边界填充额外的无障碍节点.
  • GetExtraVirtualViewAt:返回Component中指定位置的额外无障碍节点的索引.

无障碍的处理


所有的Component都支持一系列与AccessibilityDelegateCompat方法相一致的事件.
这些事件拥有它们对应的AccessibilityDelegateCompat方法的参数,和一个额外的名叫superDelegate的AccessibilityDelegateCompat参数,它允许你在必要的时候显式的调用View的无障碍方法的默认实现.

以下是支持的事件的总览:

事件 ACCESSIBILITYDELEGATE方法
DispatchPopulateAccessibilityEventEvent dispatchPopulateAccessibilityEvent
OnInitializeAccessibilityEventEvent onInitializeAccessibilityEvent
OnInitializeAccessibilityNodeInfoEvent onInitializeAccessibilityNodeInfo
OnPopulateAccessibilityEventEvent onPopulateAccessibilityEvent
OnRequestSendAccessibilityEventEvent onRequestSendAccessibilityEvent
PerformAccessibilityActionEvent performAccessibilityAction
SendAccessibilityEventEvent sendAccessibilityEvent
SendAccessibilityUncheckedEvent sendAccessibilityEventUnchecked

设置任何这些事件的处理程序将会导致在挂载的View中设置AccessibilityDelegate,当调用相应的方法时,它将调用您的事件处理程序。

如果你没有提供处理程序的方法被调用,delegate将会交由ANdroid view的默认实现去处理(类似于调用了super或者superDelegate的实现).

举例来说,下面是覆写Component中onInitializeAccessibilityNodeInfo的步骤:
1.实现一个事件处理器:

1
2
3
4
5
6
7
8
9
@OnEvent(OnInitializeAccessiblityNodeInfoEvent.class)
static void onInitializeAccessibilityNodeInfoEvent(
@FromEvent AccessibilityDelegateCompat superDelegate,
@FromEvent View view,
@FromEvent AccessibilityNodeInfoCompat node) {
// Equivalent to calling super on a regular AccessibilityDelegate, not required
superDelegate.onInitializeAccessibilityNodeInfo(view, node);
// My implementation
}

2.把时间处理器设置到component中.

1
2
3
4
Text.create(c)
.text(title)
.withLayout()
.onInitializeAccessiblityNodeInfoHandler(MyComponent.onInitializeAccessibilityNodeInfoEvent(c))

AccessibilityDelegates的一个最好的特性之一就是它的甚至可以跨越视图的可重用性.而在Litho中,这也可以通过在Component中引入一个包含我们需要的事件处理器的包装spec来实现.例如.假设我们需要一个Component,它添加了”please”到了每一个它注释的AccessibilityEvent方法中.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@LayoutSpec
class PoliteComponentWrapper {
@OnCreateLayout
static ComponentLayout onCreateLayout(
ComponentContext c,
@Prop Component<?> content) {
return Layout.create(c, content)
.onPopulateAccessibilityEventHandler(
PoliteComponentWrapper.onPopulateAccessibilityEvent(c))
.build();
}
@OnEvent(OnPopulateAccessibilityEvent.class)
static void onPopulateAccessibilityEvent(
ComponentContext c,
@FromEvent AccessibilityDelegateCompat superDelegate,
@FromEvent View view
@FromEvent AccessibilityEvent event) {
superDelegate.onPopulateAccessibilityEvent(view, event);
event.getText().add("please");
}
}

现在你可以使用PoliteComponentWrapper来替代任何你原来使用你的Component的地方了.

1
2
3
4
5
6
7
8
9
10
11
@OnCreateLayout
static ComponentLayout onCreateLayout(
ComponentContext c,
@Prop CharSequence text) {
return PoliteComponentWrapper.create(c)
.content(
Text.create(c)
.text(text))
.build();
}




回到导航页