Более миллиарда человек живут с той или иной формой инвалидности. Поэтому, создавая более доступные интерфейсы, Android-приложения могут обслуживать более широкий круг пользователей и облегчать жизнь людям с ограниченными возможностями. Доступность гарантирует, что пользователи с ограниченными возможностями зрения, слуха или двигательных функций смогут без проблем перемещаться по приложению и использовать его.
Мы подробнее рассмотрим некоторые распространенные концепции доступности, которые должны понимать все разработчики: предоставление соответствующих меток для элементов пользовательского интерфейса, обеспечение надлежащего цветового контраста, чтобы пользователи могли легко читать текст и распознавать значки, и предоставление достаточно больших сенсорных областей, чтобы пользователи могли легко взаимодействовать с приложением.
TalkBack
TalkBack — это встроенная в Android программа чтения с экрана на основе жестов. TalkBack можно найти в Settings -> Accessibility -> TalkBack -> Use TalkBack.
Когда TalkBack включен, активный элемент на экране озвучивается. TalkBack исключает предположение о том, что пользователь видит, и делает упор на его способность слышать и касаться экрана с высокой точностью. Ниже перечислены действия, которые может использовать пользователь:
- Свайп вправо — Переход к следующему элементу
- Свайп влево — Переход к предыдущему элементу
- Двойное касание — Активация элемента
- Проведение пальцем по экрану — Фокусировка на элементах
- Свайп двумя пальцами — Прокрутка
- Касание тремя пальцами — Открытие меню TalkBack
Доступность в действии
Описание содержимого
Полезное описание содержимого объясняет, что делает представление. Описание должно быть точным и лаконичным, чтобы корректно работать со службой доступности Android. Если графический элемент на экране не имеет описания содержимого, это может затруднить навигацию пользователя в приложении. TextView или его подклассы обычно отображают текст, поэтому нет необходимости указывать метки содержимого. Но важно указывать описание содержимого для ImageView, ImageButtons или любого представления, которое передает значимую или полезную информацию с помощью графики.
Возьмем, к примеру, ImageView. Этот ImageView представляет собой иконку фильтра, и при нажатии на него пользователь должен перейти на новый экран для фильтрации. Поскольку этот элемент связан с действием, следует указать, что происходит при нажатии на него. Если изображение не содержит значимой информации, его можно указать с помощью атрибута contentDescription, равного null.
<ImageView
android:id="@+id/iv_filter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="Filter Parkings" />
Что следует учитывать
- Всегда используйте локализованные строки; это позволяет переводить строку в соответствии с языковыми настройками пользователя
- Метки должны быть краткими; излишне подробные описания могут ухудшить пользовательский опыт
- Не указывайте тип элемента управления, например, кнопку, TalkBack обычно объявляет об этом самостоятельно
- Не указывайте режимы взаимодействия, например, «Нажмите, чтобы отфильтровать парковки»
- Не указывайте описания состояний, такие как «Вкл.» или «Выкл.» — описание состояния уже встроено в представления
- Для представлений, предназначенных для декоративных целей, можно установить
importantForAccessibilityв значениеno
Hint и labelFor
Представления EditText должны использовать атрибут hint для подсказки контекста. При добавлении атрибута hint TalkBack будет объявлять элемент как, например, «Поле ввода Имя пользователя». Без hint TalkBack просто объявит его как «EditText», контекст которого пользователь не сможет понять.
<EditText
android:id="@+id/et_email"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="@string/email"
android:inputType="textEmailAddress"
... />
Часто мы используем метку над полем EditText; здесь мы можем использовать атрибут labelFor для указания связи. Теперь TalkBack сначала объявит элемент Label, а затем объявит EditText под ним как «Поле ввода для имени пользователя». Это позволит пользователю понять, что нужно ввести в поле EditText.
<!-- Label for Email Id -->
<TextView
android:id="@+id/tv_email_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/email_id"
android:labelFor="@id/et_email"
... />
<EditText
android:id="@+id/et_email"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="textEmailAddress"
... />
<!-- Label for Password -->
<TextView
android:id="@+id/tv_password"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/password"
android:labelFor="@id/et_password"
... />
<EditText
android:id="@+id/et_password"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="textPassword"
... />
Списки
Для элементов в списках или коллекциях метка должна быть уникальной, чтобы пользователь не путался между несколькими элементами. Уникальное описание можно указать в рантайме, как показано ниже. Например: — RecyclerView с элементами Vehicle.
override fun onBindViewHolder(holder: VehicleViewHolder, position: Int) {
val vehicle = vehicles[position]
holder.tvVehicle.contentDescription = "Vehicle ${position}: ${vehicle.nickName}"
}
Действия для доступности
Чтобы изменить поведение по умолчанию, сделав описание более понятным, можно заменить объявление действий для специальных возможностей.
Например: у нас есть ImageView, на который пользователь нажимает, чтобы отметить элемент как избранное. По умолчанию TalkBack объявляет «Двойное касание для активации». Однако мы хотим объявлять это как «Двойное касание для добавления в избранное», чтобы пользователь понимал цель. Этого можно добиться, заменив действия специальных возможностей, как показано ниже.
ViewCompat.replaceAccessibilityAction(
targetView, // View to target
AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_CLICK,
getText(R.string.favorite), // Custom action
null
)
Кастомные описания состояний
Некоторые виджеты Android, такие как CheckBox и Switch, содержат состояния, которые они предоставляют службе специальных возможностей. Например, CheckBox имеет два состояния, которые TalkBack объявляет как «Отмечено» и «Не отмечено». Аналогично, «Включено» и «Выключено» для Switch. Можно настроить описания этих состояний для улучшения пользовательского опыта.
ViewCompat.setAccessibilityDelegate(targetView, object : AccessibilityDelegateCompat() {
override fun onInitializeAccessibilityNodeInfo(
host: View,
info: AccessibilityNodeInfoCompat
) {
super.onInitializeAccessibilityNodeInfo(host, info)
info.addAction(
AccessibilityNodeInfoCompat.AccessibilityActionCompat(
AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_CLICK.id,
if (targetView.isChecked) {
"Turn off app notifications"
}
else {
"Turn on app notifications"
}
)
)
}
})
Теперь этот переключатель будет объявлять стандартное действие щелчка как «Двойное касание для включения уведомлений приложения», если флажок не отмечен, и «Двойное касание для выключения уведомлений приложения», если флажок стоит.
Полезные атрибуты
Мы можем использовать такие атрибуты, как android:accessibilityTraversalBefore и android:accessibilityTraversalAfter, для управления порядком фокусировки специальных возможностей, если это необходимо. В противном случае, используйте правильную последовательность и структуру макета для установки порядка фокусировки специальных возможностей.
Чтобы сгруппировать контент, заключите все соответствующие элементы контента в один ViewGroup макета и установите для этого ViewGroup свойства android:importantForAccessibility=”yes” и android:focusable=”true”. Эти свойства делают ViewGroup доступным для фокусировки программой чтения с экрана и указывают программе чтения с экрана объединить весь текст дочерних элементов в одно объявление.
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:importantForAccessibility="yes"
android:focusable="true"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/tv_movie_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:layout_marginStart="25dp"
android:textSize="30sp"
android:text="Avatar"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_movie_des"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginStart="25dp"
android:accessibilityTraversalAfter="@id/tv_movie_name"
android:textSize="20sp"
android:text="Avatar is a 2009 epic science fiction film written and directed by James Cameron."
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_movie_name" />
</androidx.constraintlayout.widget.ConstraintLayout>
Контраст
Когда цвета фона и переднего плана элементов пользовательского интерфейса имеют недостаточный контраст, текст может быть трудночитаемым, а значки — трудноразличимыми. Правильный цветовой контраст помогает пользователям с нарушениями зрения.
Крупный текст, с размером более 18dp или 14dp и более (если он жирный), должен иметь соотношение контрастности 3 к 1.
Для проверки достаточного цветового контраста можно использовать веб-инструменты, такие как Contrast Checker. Или можно использовать окно Problems в Android Studio для проверки макета, которое предоставляет предупреждение и предложение по улучшению для элементов, имеющих недостаточный цветовой контраст текста.
Размер области касания
Области касания элементов должны быть не менее 48dp на 48dp (чем больше, тем лучше), чтобы обеспечить надежное взаимодействие. Существует несколько способов достижения подходящего размера области касания, например, можно установить ширину или высоту в 48dp, если содержимое/рисунок имеет такой размер или меньше. Или можно добавить отступы, чтобы обеспечить минимальный размер области касания. Установка android:minWidth и android:minHeight в 48dp является наиболее предпочтительным методом и хорошо подходит для других элементов, к которым можно прикоснуться. В последней версии Android Studio панель проблем также будет отмечать область касания, и мы можем устранить эти конкретные предупреждения, обеспечив минимальный рекомендуемый размер области касания для элементов, на которые можно нажать.
<ImageButton
android:id="@+id/iv_filter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="12dp"
android:src="@drawable/ic_angle_right_outline"
android:contentDescription="Next" />
<!-- icon is of 24dpX24dp -->
<!-- 12dp of padding will expand the button appropriately to recommended size. -->
Приложение «Сканер доступности»
«Сканер доступности» (Accessibility Scanner) — это инструмент, который может помочь нам в тестировании доступности. Сканер сканирует экран и предлагает способы улучшения доступности вашего приложения, используя встроенный фреймворк тестирования. Он предоставляет конкретные рекомендации после анализа таких параметров, как метки контента, размер области касания, кликабельные элементы и цветовой контраст текста и значков.
Как использовать сканер:
- Откройте приложение и следуйте инструкциям, чтобы включить службу сканирования специальных возможностей
- Перейдите к приложению, которое вы хотите просканировать, и нажмите плавающую кнопку
- Выберите выполнение одного сканирования или запись всего пользовательского пути на нескольких экранах
Пример:
Заключение
В этом руководстве мы узнали, как используя инструменты Android создавать приложения, доступные для всех. Обеспечение корректного описания контента, удобных сенсорных областей и читаемого цветового контраста — это простые шаги, которые сделают наше приложение более доступным и удовлетворят потребности каждого пользователя.

