Suporte à acessibilidade de visualização personalizada no Android TV

Embora muitos apps para Android TV sejam criados com componentes nativos do Android, ele é também é importante considerar a acessibilidade frameworks ou componentes, especialmente ao usar visualizações personalizadas.

Os componentes de visualização personalizados que fazem a interface direta com o OpenGL ou o Canvas podem não funcionar bem com serviços de acessibilidade, como o TalkBack e o acesso com interruptor.

Considere alguns dos seguintes problemas que podem ocorrer ao usar o TalkBack em:

  • O foco da acessibilidade (um retângulo verde) pode desaparecer do app.
  • O foco de acessibilidade pode selecionar o limite de toda a tela.
  • O foco de acessibilidade pode não ser móvel.
  • As quatro teclas de direção do botão direcional podem não ter efeito, mesmo que o código as processe.

Se você notar algum desses problemas no seu app, verifique se o o app expõe seu AccessibilityNodeInfo aos serviços de acessibilidade.

O restante deste guia fornece algumas soluções e práticas recomendadas para lidar com esses problemas.

Eventos de botão direcional são consumidos pelos serviços de acessibilidade

A causa raiz desse problema é que os eventos principais são consumidos pela acessibilidade serviços.

Consumo de eventos do botão Dpad Figura 1. Diagramas mostrando como o sistema funciona com o TalkBack ativado e desativado.

Como ilustrado na figura 1, quando o TalkBack é ativado, os eventos do botão direcional não são passados para o manipulador D-pad definido pelo desenvolvedor. Em vez disso, os serviços de acessibilidade recebem os eventos-chave para que possam mover foco na acessibilidade. Como os componentes personalizados do Android não expõem por padrão, informações aos serviços de acessibilidade sobre a posição deles na tela; os serviços de acessibilidade não podem mover o foco da acessibilidade para destacá-los.

Outros serviços de acessibilidade são afetados de forma semelhante: eventos de botão direcional também podem ser consumida ao usar o acesso com interruptor.

Como os eventos D-pad são enviados para serviços de acessibilidade e esse serviço não sabe onde estão os componentes da IU em uma visualização personalizada, Implemente AccessibilityNodeInfo para que seu app encaminhe o eventos de teclas corretamente.

Expor informações aos serviços de acessibilidade

Fornecer aos serviços de acessibilidade informações suficientes sobre a localização e descrição de visualizações personalizadas, implementar AccessibilityNodeInfo para expor detalhes de cada componente. Definir a relação lógica de visualizações para que os serviços de acessibilidade possam gerenciar o foco, implementar ExploreByTouchHelper e configurá-la usando ViewCompat.setAccessibilityDelegate(View, AccessibilityDelegateCompat) para visualizações personalizadas.

Ao implementar ExploreByTouchHelper, substitua os quatro métodos abstratos:

Kotlin

// Return the virtual view ID whose view is covered by the input point (x, y).
protected fun getVirtualViewAt(x: Float, y: Float): Int

// Fill the virtual view ID list into the input parameter virtualViewIds.
protected fun getVisibleVirtualViews(virtualViewIds: List<Int>)

// For the view whose virtualViewId is the input virtualViewId, populate the
// accessibility node information into the AccessibilityNodeInfoCompat parameter.
protected fun onPopulateNodeForVirtualView(virtualViewId: Int, @NonNull node: AccessibilityNodeInfoCompat)

// Set the accessibility handling when perform action.
protected fun onPerformActionForVirtualView(virtualViewId: Int, action: Int, @Nullable arguments: Bundle): Boolean

Java

// Return the virtual view ID whose view is covered by the input point (x, y).
protected int getVirtualViewAt(float x, float y)

// Fill the virtual view ID list into the input parameter virtualViewIds.
protected void getVisibleVirtualViews(List<Integer> virtualViewIds)

// For the view whose virtualViewId is the input virtualViewId, populate the
// accessibility node information into the AccessibilityNodeInfoCompat parameter.
protected void onPopulateNodeForVirtualView(int virtualViewId, @NonNull AccessibilityNodeInfoCompat node)

// Set the accessibility handling when perform action.
protected boolean onPerformActionForVirtualView(int virtualViewId, int action, @Nullable Bundle arguments)

Para mais detalhes, assista ao vídeo Google I/O 2013 - Capacitando pessoas cegas e com baixa visão Acessibilidade no Android (em inglês) ou leia mais sobre como preencher eventos de acessibilidade.

Práticas recomendadas

Exemplo

Consulte o exemplo de acessibilidade de visualização personalizada do Android TV para conferir as práticas recomendadas para: adicionar suporte à acessibilidade para apps que usam visualizações personalizadas.