Molte app per Android TV includono componenti Android nativi, ma è importante considerare anche l'accessibilità framework o componenti, in particolare quando si utilizzano le viste personalizzate.
I componenti della visualizzazione personalizzata che si interfacciano direttamente con OpenGL o Canvas potrebbero non funzionare correttamente con servizi di accessibilità come Talkback e Switch Access.
Considera alcuni dei seguenti problemi che potrebbero verificarsi se TalkBack viene cambiato su:
- Il focus accessibilità (un rettangolo verde) potrebbe scomparire nell'app.
- L'elemento attivo dell'accessibilità potrebbe selezionare il bordo dell'intero schermo.
- L'elemento attivo con accessibilità potrebbe non essere spostabile.
- I quattro tasti direzionali del D-pad potrebbero non avere effetto, anche se il codice li gestisce.
Se riscontri uno di questi problemi nella tua app, controlla che
app espone il proprio AccessibilityNodeInfo
ai servizi di accessibilità.
La parte restante di questa guida fornisce alcune soluzioni e best practice per risolvere questi problemi.
Gli eventi con il D-pad vengono consumati dai servizi di accessibilità
La causa principale di questo problema è che gli eventi chiave vengono consumati dall'accessibilità i servizi di machine learning.
Come illustrato nella Figura 1, quando TalkBack è attivo, gli eventi D-pad non vengono passate al gestore D-pad definito dallo sviluppatore. Invece, di accessibilità ricevono gli eventi chiave per e accessibilità. 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 lo stato attivo di accessibilità per evidenziarli.
Altri servizi di accessibilità sono interessati in modo simile: anche gli eventi D-pad potrebbero essere consumate quando si utilizza Switch Access.
Poiché gli eventi relativi al D-pad vengono inviati ai servizi di accessibilità e
il servizio non sa dove si trovano i componenti dell'interfaccia utente in una vista personalizzata,
devi implementare AccessibilityNodeInfo
affinché la tua app possa inoltrare
gli eventi chiave in modo corretto.
Esporre informazioni ai servizi di accessibilità
Fornire ai servizi di accessibilità informazioni sufficienti sul
posizione e descrizione delle viste personalizzate, implementa AccessibilityNodeInfo
per visualizzare i dettagli di ciascun componente.
Definire la relazione logica delle viste in modo che i servizi di accessibilità possano
gestire l'attenzione, implementare ExploreByTouchHelper
e impostarla utilizzando
ViewCompat.setAccessibilityDelegate(View, AccessibilityDelegateCompat)
per le viste personalizzate.
Quando implementi ExploreByTouchHelper
, sostituisci i 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 ulteriori dettagli, guarda il video Google I/O 2013 - Blind and Low-Vision Accessibilità su Android oppure scopri di più sulla compilazione degli eventi di accessibilità.
Best practice
Obbligatorio:
AccessibilityNodeInfo.getBoundsInScreen()
deve definire la posizione del componente.Obbligatorio:
AccessibilityNodeInfo.setVisibleToUser()
deve rispecchiare la visibilità del componente.Obbligatorio:
AccessibilityNodeInfo.getContentDescription()
devi specificare la descrizione dei contenuti che TalkBack dovrà annunciare.Specifica
AccessibilityNodeInfo.setClassName()
per consentire ai servizi di distinguere il tipo di componente.Quando implementi
performAction()
, riflettere l'azione utilizzando unAccessibilityEvent
corrispondente.Per implementare altri tipi di azione, ad esempio
ACTION_CLICK
, richiamaAccessibilityNodeInfo.addAction(ACTION_CLICK)
utilizzando la logica corrispondente inperformAction()
.Se applicabile, rispecchia lo stato del componente per
setFocusable()
,setClickable()
,setScrollable()
, e metodi simili.Consulta la documentazione di
AccessibilityNodeInfo
per identificare altri modi con cui i servizi di accessibilità possono interagire meglio dai componenti.
Anteprima
Consulta l'esempio di accessibilità in visualizzazione personalizzata per Android TV per conoscere le best practice per aggiunta del supporto dell'accessibilità alle app utilizzando le visualizzazioni personalizzate.