Хотя многие приложения Android TV созданы с использованием собственных компонентов Android, также важно учитывать доступность сторонних платформ или компонентов, особенно при использовании пользовательских представлений .
Компоненты пользовательского представления, взаимодействующие напрямую с OpenGL или Canvas, могут не работать должным образом со службами специальных возможностей, такими как Talkback и Switch Access.
Рассмотрим некоторые из следующих проблем, которые могут возникнуть при включении Talkback:
- Фокус доступности (зеленый прямоугольник) может исчезнуть в вашем приложении.
- Фокус специальных возможностей может выбрать границу всего экрана.
- Фокус специальных возможностей может быть неподвижным.
- Четыре клавиши направления на D-pad могут не иметь никакого эффекта, даже если ваш код их обрабатывает.
Если вы заметили какую-либо из этих проблем в своем приложении, убедитесь, что ваше приложение предоставляет свое дерево AccessibilityNodeInfo
службам специальных возможностей.
В оставшейся части руководства представлены некоторые решения и лучшие практики для решения этих проблем.
События D-pad используются службами специальных возможностей
Основная причина этой проблемы заключается в том, что ключевые события используются службами доступности.
Как показано на рисунке 1, когда Talkback включен, события крестовины не передаются обработчику крестовины, определенному разработчиком. Вместо этого службы доступности получают ключевые события, чтобы они могли переместить фокус доступности. Поскольку пользовательские компоненты Android по умолчанию не предоставляют службам специальных возможностей информацию об их положении на экране, службы специальных возможностей не могут перемещать фокус специальных возможностей, чтобы выделить их.
Аналогичное влияние затронуто и другие службы специальных возможностей: события D-pad также могут использоваться при использовании Switch Access.
Поскольку события D-pad передаются в службы специальных возможностей, и эта служба не знает, где находятся компоненты пользовательского интерфейса в пользовательском представлении, вы должны реализовать AccessibilityNodeInfo
, чтобы ваше приложение правильно пересылало ключевые события.
Предоставлять информацию службам доступности
Чтобы предоставить службам специальных возможностей достаточную информацию о местонахождении и описании пользовательских представлений, реализуйте AccessibilityNodeInfo
, чтобы предоставлять сведения для каждого компонента. Чтобы определить логическую связь представлений, чтобы службы специальных возможностей могли управлять фокусом, реализуйте ExploreByTouchHelper
и установите его с помощью ViewCompat.setAccessibilityDelegate(View, AccessibilityDelegateCompat)
для пользовательских представлений.
При реализации ExploreByTouchHelper
переопределите его четыре абстрактных метода:
Котлин
// 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
Ява
// 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)
Для получения более подробной информации посмотрите Google I/O 2013 — Включение специальных возможностей для слепых и слабовидящих на Android или узнайте больше о заполнении событий доступности .
Лучшие практики
Обязательно:
AccessibilityNodeInfo.getBoundsInScreen()
должен определять положение компонента.Обязательно:
AccessibilityNodeInfo.setVisibleToUser()
должен отражать видимость компонента.Обязательно:
AccessibilityNodeInfo.getContentDescription()
должен указать описание контента, который будет объявлен Talkback.Укажите
AccessibilityNodeInfo.setClassName()
, чтобы службы могли различать тип компонента.При реализации
performAction()
отразите действие, используя соответствующийAccessibilityEvent
.Чтобы реализовать больше типов действий, таких как
ACTION_CLICK
, вызовитеAccessibilityNodeInfo.addAction(ACTION_CLICK)
используя соответствующую логику вperformAction()
.Если применимо, отразите состояние компонента для
setFocusable()
,setClickable()
,setScrollable()
и подобных методов.Просмотрите документацию
AccessibilityNodeInfo
, чтобы определить другие способы, с помощью которых службы специальных возможностей могут лучше взаимодействовать с вашими компонентами.
Образец
Ознакомьтесь с примером специальных возможностей пользовательского представления для Android TV, чтобы узнать рекомендации по добавлению поддержки специальных возможностей в приложения с использованием пользовательских представлений.