Las aplicaciones para TV a veces tienen casos de uso que dificultan que los usuarios que dependen de TalkBack para usar la app. Para brindar una mejor experiencia con TalkBack usuarios, revisa cada una de las secciones de esta guía e implementa cambios en tu cuando sea necesario. Si tu app usa vistas personalizadas, también debes consultar el guía correspondiente en la que se describe cómo admitir la accesibilidad con vistas.
Cómo controlar vistas anidadas
Las vistas anidadas pueden resultar difíciles de navegar para los usuarios de TalkBack. Siempre que sea posible, asegúrate la vista principal o secundaria en la que TalkBack puede enfocarse, pero no ambas.
Para que TalkBack pueda enfocar una vista, establece focusable
y la
El atributo focusableInTouchMode
a true
. Este paso es necesario porque
algunos dispositivos de TV pueden entrar y salir del modo táctil mientras TalkBack está activo.
Para que una vista no se pueda enfocar, basta con configurar focusable
.
a false
. Sin embargo, si la vista es accionable (es decir,
el AccessibilityNodeInfo
correspondiente tiene ACTION_CLICK
), es posible que todavía
ser enfocables.
Cómo cambiar las descripciones de Acciones
De forma predeterminada, TalkBack anuncia "Presiona Seleccionar para activar". para obtener vistas prácticas. Para algunas acciones, se usa el término "activar" podría no ser una buena descripción. Para proporcionar una descripción más precisa, puedes cambiarla:
Kotlin
findViewById<View>(R.id.custom_actionable_view).accessibilityDelegate = object : View.AccessibilityDelegate() { override fun onInitializeAccessibilityNodeInfo(host: View, info: AccessibilityNodeInfo) { super.onInitializeAccessibilityNodeInfo(host, info) info.addAction( AccessibilityAction( AccessibilityAction.ACTION_CLICK.id, getString(R.string.custom_label) ) ) } }
Java
findViewById(R.id.custom_actionable_view).setAccessibilityDelegate(new AccessibilityDelegate() { @Override public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) { super.onInitializeAccessibilityNodeInfo(host, info); AccessibilityAction action = new AccessibilityAction( AccessibilityAction.ACTION_CLICK.getId(), getString(R.string.custom_label)); info.addAction(action); } });
Cómo agregar compatibilidad con controles deslizantes
TalkBack en TV tiene una compatibilidad especial con los controles deslizantes. Para habilitar el modo de control deslizante, agrega
ACTION_SET_PROGRESS
a una vista junto con un objeto RangeInfo
El usuario ingresa al modo deslizante al presionar el botón central del control remoto de la TV.
En este modo, los botones de flecha generan ACTION_SCROLL_FORWARD
y
ACTION_SCROLL_BACKWARD
acciones de accesibilidad.
En el siguiente ejemplo, se implementa un control deslizante de volumen con niveles del 1 al 10:
Kotlin
/** * This example only provides slider functionality for TalkBack users. Additional logic should * be added for other users. Such logic may reuse the increase and decrease methods. */ class VolumeSlider(context: Context?, attrs: AttributeSet?) : LinearLayout(context, attrs) { private val min = 1 private val max = 10 private var current = 5 private var textView: TextView? = null init { isFocusable = true isFocusableInTouchMode = true val rangeInfo = AccessibilityNodeInfo.RangeInfo( AccessibilityNodeInfo.RangeInfo.RANGE_TYPE_INT, min.toFloat(), max.toFloat(), current.toFloat() ) accessibilityDelegate = object : AccessibilityDelegate() { override fun onInitializeAccessibilityNodeInfo(host: View, info: AccessibilityNodeInfo) { super.onInitializeAccessibilityNodeInfo(host, info) info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SET_PROGRESS) info.rangeInfo = rangeInfo } override fun performAccessibilityAction(host: View, action: Int, args: Bundle?): Boolean { if (action == AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_FORWARD.id) { increase() return true } if (action == AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_BACKWARD.id) { decrease() return true } return super.performAccessibilityAction(host, action, args) } } } override fun onFinishInflate() { super.onFinishInflate() textView = findViewById(R.id.text) textView!!.text = context.getString(R.string.level, current) } private fun increase() { update((current + 1).coerceAtMost(max)) } private fun decrease() { update((current - 1).coerceAtLeast(min)) } private fun update(newLevel: Int) { if (textView == null) { return } val newText = context.getString(R.string.level, newLevel) // Update the user interface with the new volume. textView!!.text = newText // Announce the new volume. announceForAccessibility(newText) current = newLevel } }
Java
/** * This example only provides slider functionality for TalkBack users. Additional logic should * be added for other users. Such logic can reuse the increase and decrease methods. */ public class VolumeSlider extends LinearLayout { private final int min = 1; private final int max = 10; private int current = 5; private TextView textView; public VolumeSlider(Context context, AttributeSet attrs) { super(context, attrs); setFocusable(true); setFocusableInTouchMode(true); RangeInfo rangeInfo = new RangeInfo(RangeInfo.RANGE_TYPE_INT, min, max, current); setAccessibilityDelegate( new AccessibilityDelegate() { @Override public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) { super.onInitializeAccessibilityNodeInfo(host, info); info.addAction(AccessibilityAction.ACTION_SET_PROGRESS); info.setRangeInfo(rangeInfo); } @Override public boolean performAccessibilityAction(View host, int action, Bundle args) { if (action == AccessibilityAction.ACTION_SCROLL_FORWARD.getId()) { increase(); return true; } if (action == AccessibilityAction.ACTION_SCROLL_BACKWARD.getId()) { decrease(); return true; } return super.performAccessibilityAction(host, action, args); } }); } @Override protected void onFinishInflate() { super.onFinishInflate(); textView = findViewById(R.id.text); textView.setText(getContext().getString(R.string.level, current)); } private void increase() { update(Math.min(current + 1, max)); } private void decrease() { update(Math.max(current - 1, min)); } private void update(int newLevel) { if (textView == null) { return; } String newText = getContext().getString(R.string.level, newLevel); // Update the user interface with the new volume. textView.setText(newText); // Announce the new volume. announceForAccessibility(newText); current = newLevel; } }