Supporto dell'accessibilità della visualizzazione personalizzata su Android TV

Sebbene molte app Android TV siano sviluppate con componenti Android nativi, è importante considerare anche l'accessibilità di frame o componenti di terze parti, soprattutto quando si utilizzano le visualizzazioni personalizzate.

I componenti delle visualizzazioni personalizzate che si interfacciano direttamente con OpenGL o Canvas potrebbero non funzionare correttamente con i servizi di accessibilità come TalkBack e Switch Access.

Considera alcuni dei seguenti problemi che potrebbero verificarsi quando TalkBack è attivo:

  • Lo stato attivo di accessibilità (un rettangolo verde) potrebbe non essere più visualizzato nell'app.
  • L'impostazione Accessibilità potrebbe selezionare i confini dell'intero schermo.
  • L'elemento attivo con requisiti di accessibilità potrebbe non essere spostabile.
  • I quattro tasti di direzione del D-pad potrebbero non avere alcun effetto, anche se è in corso la gestione del codice.

Se rilevi uno di questi problemi nella tua app, verifica che l'app mostri la sua struttura AccessibilityNodeInfo ai servizi di accessibilità.

La parte rimanente di questa guida fornisce alcune soluzioni e best practice per risolvere questi problemi.

Gli eventi D-pad vengono utilizzati dai servizi di accessibilità

La causa principale di questo problema è che i servizi di accessibilità utilizzano gli eventi chiave.

Consumo di eventi Dpad Figura 1. Diagrammi che mostrano il funzionamento del sistema con TalkBack attivato e disattivato.

Come illustrato nella figura 1, quando TalkBack è attivo, gli eventi del D-pad non vengono trasmessi al gestore del D-pad definito dallo sviluppatore. Al contrario, i servizi di accessibilità ricevono gli eventi chiave in modo da poter spostare l'attenzione sull'accessibilità. Poiché i componenti Android personalizzati non espongono per impostazione predefinita informazioni ai servizi di accessibilità sulla loro posizione sullo schermo, i servizi di accessibilità non possono spostare l'elemento attivo sull'accessibilità per evidenziarli.

Anche altri servizi di accessibilità sono interessati da questo problema: quando si usa Switch Access, potrebbero essere consumati anche gli eventi D-pad.

Poiché gli eventi D-pad vengono inviati ai servizi di accessibilità e questo servizio non sa dove si trovano i componenti UI in una vista personalizzata, devi implementare AccessibilityNodeInfo affinché la tua app possa inoltrare correttamente gli eventi chiave.

Esporre le informazioni ai servizi di accessibilità

Per fornire ai servizi di accessibilità informazioni sufficienti sulla posizione e sulla descrizione delle viste personalizzate, implementa AccessibilityNodeInfo per mostrare i dettagli di ogni componente. Per definire la relazione logica delle viste in modo che i servizi di accessibilità possano gestire lo stato attivo, implementa ExploreByTouchHelper e impostalo utilizzando ViewCompat.setAccessibilityDelegate(View, AccessibilityDelegateCompat) per le viste personalizzate.

Quando implementi ExploreByTouchHelper, esegui l'override dei suoi quattro metodi astratti:

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)

Per maggiori dettagli, guarda il video Google I/O 2013 - Abilitazione dell'accessibilità per persone cieche e ipovedenti su Android o leggi ulteriori informazioni sulla compilazione degli eventi di accessibilità.

Best practice

Anteprima

Consulta l'esempio di accessibilità con visualizzazione personalizzata per Android TV per conoscere le best practice per aggiungere il supporto dell'accessibilità alle app che utilizzano la visualizzazione personalizzata.