Algumas pessoas que usam dispositivos Android têm necessidades de acessibilidade diferentes de outras. Para ajudar determinado grupo da população que tem a mesma necessidade de acessibilidade, o framework do Android oferece a possibilidade de os desenvolvedores criarem um serviço de acessibilidade, que apresenta o conteúdo dos apps e os opera em nome deles.
O Android fornece vários serviços de acessibilidade do sistema, incluindo:
- TalkBack: ajuda pessoas com baixa visão ou cegas. Anuncia o conteúdo por meio de uma voz sintetizada e realiza ações em um app em resposta a gestos do usuário.
- Acesso com interruptor: ajuda pessoas com deficiências motoras. Destaca elementos interativos e realiza ações em resposta ao pressionamento de um botão. Permite controlar o dispositivo usando apenas um ou dois botões.
Para ajudar as pessoas com necessidades de acessibilidade a usar seu app, ele precisa seguir as práticas recomendadas descritas nesta página. Elas se baseiam nas principais diretrizes descritas em Tornar os apps mais acessíveis.
Cada uma das práticas recomendadas a seguir pode melhorar ainda mais a acessibilidade do seu app:
- Elementos de etiqueta
- Os usuários precisam entender o conteúdo e a finalidade de cada elemento interativo e significativo da IU no seu app.
- Usar ou estender widgets do sistema
- Crie com base nos elementos de visualização que o framework inclui, em vez de criar suas próprias visualizações personalizadas. As classes de visualização e widget do framework já oferecem a maioria dos recursos de acessibilidade necessários para seu app.
- Usar outras indicações além da cor
- Os usuários precisam conseguir distinguir claramente as categorias de elementos em uma IU. Para fazer isso, use padrões e posicionamento junto à cor para expressar essas diferenças.
- Tornar o conteúdo de mídia mais acessível
- Tente adicionar descrições ao conteúdo de áudio ou vídeo do seu app para que os usuários que consomem esse conteúdo não precisem depender de indicações completamente visuais ou auditivas.
Elementos de etiqueta
É importante oferecer aos usuários etiquetas descritivas e úteis para cada elemento de IU interativo do seu app. Cada etiqueta precisa explicar o significado e a finalidade de um elemento específico. Leitores de tela como o "TalkBack" podem anunciar essas etiquetas para os usuários que dependem desses serviços.
Na maioria dos casos, a descrição de um determinado elemento de IU é especificada no arquivo de
recurso de layout que contém esse elemento. Embora você geralmente adicione etiquetas usando
o atributo contentDescription
, conforme explicado no guia Tornar os apps
mais acessíveis, há várias outras técnicas de classificação que podem ser usadas, conforme descrito
nas seções a seguir.
Elementos editáveis
Ao classificar elementos editáveis, como
objetos EditText
, é interessante mostrar um
texto que dê exemplos de entrada válida no próprio elemento, além de
disponibilizar esse exemplo de texto para os leitores de tela. Nessas situações, é
possível usar o atributo android:hint
, como mostrado no snippet a seguir:
<!-- The hint text for en-US locale would be "Apartment, suite, or building". --> <EditText android:id="@+id/addressLine2" android:hint="@string/aptSuiteBuilding" ... />
Nessa situação, o objeto View
precisa ter o atributo android:labelFor
definido como ID do
elemento EditText
. Para mais detalhes, consulte a seção que descreve como
etiquetar pares de elementos em que um descreve o outro.
Pares de elementos em que um descreve o outro
É comum que determinado elemento EditText
tenha um objeto View
correspondente que descreve o conteúdo que
os usuários precisam inserir no elemento EditText
. Em dispositivos com o Android
4.2 (API nível 17) ou versões mais recentes, você pode indicar essa relação definindo
o atributo android:labelFor
do objeto View
.
Um exemplo de classificação desses pares de elementos aparece no snippet a seguir:
<!-- Label text for en-US locale would be "Username:" --> <TextView android:id="@+id/usernameLabel" ... android:text="@string/username" android:labelFor="@+id/usernameEntry" /> <EditText android:id="@+id/usernameEntry" ... /> <!-- Label text for en-US locale would be "Password:" --> <TextView android:id="@+id/passwordLabel" ... android:text="@string/password android:labelFor="@+id/passwordEntry" /> <EditText android:id="@+id/passwordEntry" android:inputType="textPassword" ... />
Elementos em uma coleção
Ao adicionar etiquetas aos elementos de uma coleção, cada etiqueta deve ser única. Dessa forma, os serviços de acessibilidade do sistema podem se referir a exatamente um elemento na tela quando anunciam uma etiqueta. Essa correspondência permite que os usuários saibam quando percorreram a IU ou mudaram o foco para um elemento que já conhecem.
Especificamente, inclua texto extra ou informações contextuais em
elementos dentro de layouts reutilizados, como
objetos RecyclerView
,
para que cada elemento filho seja identificado de forma exclusiva.
Para fazer isso, defina a descrição do conteúdo como parte da implementação do adaptador, conforme mostrado no snippet de código a seguir:
Kotlin
data class MovieRating(val title: String, val starRating: Integer) class MyMovieRatingsAdapter(private val myData: Array<MovieRating>): RecyclerView.Adapter<MyMovieRatingsAdapter.MyRatingViewHolder>() { class MyRatingViewHolder(val ratingView: ImageView) : RecyclerView.ViewHolder(ratingView) override fun onBindViewHolder(holder: MyRatingViewHolder, position: Int) { val ratingData = myData[position] holder.ratingView.contentDescription = "Movie ${position}: " + "${ratingData.title}, ${ratingData.starRating} stars" } }
Java
public class MovieRating { private String title; private int starRating; // ... public String getTitle() { return title; } public int getStarRating() { return starRating; } } public class MyMovieRatingsAdapter extends RecyclerView.Adapter<MyAdapter.MyRatingViewHolder> { private MovieRating[] myData; public static class MyRatingViewHolder extends RecyclerView.ViewHolder { public ImageView ratingView; public MyRatingViewHolder(ImageView iv) { super(iv); ratingView = iv; } } @Override public void onBindViewHolder(MyRatingViewHolder holder, int position) { MovieRating ratingData = myData[position]; holder.ratingView.setContentDescription("Movie " + position + ": " + ratingData.getTitle() + ", " + ratingData.getStarRating() + " stars") } }
Grupos de conteúdo relacionado
Caso seu app exiba vários elementos de IU que formam um grupo natural, como
detalhes de uma música ou atributos de uma mensagem, organize esses elementos em um
contêiner, que geralmente é uma subclasse de ViewGroup
. Defina o atributo
android:screenReaderFocusable
do objeto de contêiner
como true
e o atributo android:focusable
de cada objeto interno
como false
. Ao fazer isso, os serviços de acessibilidade podem apresentar as descrições
de conteúdo dos elementos internos, um após o outro, em um único anúncio.
Essa consolidação de elementos relacionados ajuda os usuários de tecnologia adaptativa
a descobrir as informações exibidas na tela com mais eficiência.
O snippet a seguir contém partes de conteúdo que se relacionam.
Portanto, o elemento de contêiner, uma instância de ConstraintLayout
, tem o
atributo android:screenReaderFocusable
definido como true
, e os elementos
TextView
internos têm o atributo android:focusable
definido como false
:
<!-- In response to a single user interaction, accessibility services announce both the title and the artist of the song. --> <ConstraintLayout android:id="@+id/song_data_container" ... android:screenReaderFocusable="true"> <TextView android:id="@+id/song_title" ... android:focusable="false" android:text="@string/my_song_title" /> <TextView android:id="@+id/song_artist" android:focusable="false" android:text="@string/my_songwriter" /> </ConstraintLayout>
Como os serviços de acessibilidade anunciam as descrições dos elementos internos em uma única expressão, é importante manter cada descrição o mais curta possível, sem deixar de transmitir o significado do elemento.
Etiqueta de grupo personalizada
Se você quiser, poderá modificar o agrupamento e a ordem padrão da plataforma referentes às descrições de elementos internos de um grupo. Para isso, disponibilize uma descrição de conteúdo para o próprio grupo.
O snippet a seguir mostra um exemplo de descrição de grupo personalizada:
<!-- In response to a single user interaction, accessibility services announce the custom content description for the group. --> <ConstraintLayout android:id="@+id/song_data_container" ... android:screenReaderFocusable="true" android:contentDescription="@string/title_artist_best_song"> <TextView android:id="@+id/song_title" ... <!-- Content ignored by accessibility services --> android:text="@string/my_song_title" /> <TextView android:id="@+id/song_artist" <!-- Content ignored by accessibility services --> android:text="@string/my_songwriter" /> </ConstraintLayout>
Grupos aninhados
Se a interface do seu app apresentar informações multidimensionais, como uma
lista diária de eventos de um festival, use o atributo
android:screenReaderFocusable
nos contêineres do grupo interno. Esse esquema de classificação oferece um bom
equilíbrio entre o número de anúncios necessários para descobrir o conteúdo da tela
e a duração de cada anúncio.
O snippet de código a seguir mostra um método para classificar grupos dentro de outros maiores:
<!-- In response to a single user interaction, accessibility services announce the events for a single stage only. --> <ConstraintLayout android:id="@+id/festival_event_table" ... > <ConstraintLayout android:id="@+id/stage_a_event_column" android:screenReaderFocusable="true"> <!-- UI elements that describe the events on Stage A. --> </ConstraintLayout> <ConstraintLayout android:id="@+id/stage_b_event_column" android:screenReaderFocusable="true"> <!-- UI elements that describe the events on Stage B. --> </ConstraintLayout> </ConstraintLayout>
Títulos no texto
Alguns apps usam títulos para resumir grupos de texto que aparecem na tela. Se
determinado elemento View
representa um título, você pode indicar a finalidade dele
para os serviços de acessibilidade definindo o atributo
android:accessibilityHeading
do elemento como
true
.
Os usuários de serviços de acessibilidade podem optar por navegar entre títulos em vez de entre parágrafos ou palavras. Essa flexibilidade melhora a experiência de navegação de texto.
Títulos do painel de acessibilidade
No Android 9 (API nível 28) ou versões mais recentes, você pode fornecer títulos de fácil acessibilidade para os painéis de uma tela. Para fins de acessibilidade, um painel é uma parte visualmente distinta de uma janela, como o conteúdo de um fragmento. Para que os serviços de acessibilidade entendam o comportamento semelhante a janelas de um painel, disponibilize títulos descritivos para os painéis do seu app. Os serviços de acessibilidade podem oferecer informações mais detalhadas aos usuários quando a aparência ou o conteúdo de um painel muda.
Para especificar o título de um painel, use o atributo
android:accessibilityPaneTitle
,
conforme mostrado no snippet a seguir:
<!-- Accessibility services receive announcements about content changes that are scoped to either the "shopping cart view" section (top) or "browse items" section (bottom) --> <MyShoppingCartView android:id="@+id/shoppingCartContainer" android:accessibilityPaneTitle="@string/shoppingCart" ... /> <MyShoppingBrowseView android:id="@+id/browseItemsContainer" android:accessibilityPaneTitle="@string/browseProducts" ... />
Elementos decorativos
Se um elemento na sua IU existir apenas para fins de espaçamento visual
ou aparência, defina o atributo
android:contentDescription
como "null"
.
Se o app for compatível somente com dispositivos que executam o Android 4.1 (API nível 16) ou
versões mais recentes, você poderá definir os atributos android:importantForAccessibility
desses elementos
puramente decorativos como "no"
.
Estender widgets do sistema
Ponto-chave: ao criar a IU do seu app, use ou estenda
widgets fornecidos pelo sistema que estejam o mais abaixo possível na hierarquia de classes
do Android. Os widgets fornecidos pelo sistema que estão muito abaixo na hierarquia já
têm a maioria dos recursos de acessibilidade necessários para seu app. É mais fácil
estender esses widgets fornecidos pelo sistema do que criar seus widgets a partir das classes mais
genéricas View
,
ViewCompat
,
Canvas
e
CanvasCompat
.
Se você precisar estender View
ou Canvas
diretamente, o
que pode ser necessário para uma experiência ou nível de jogo altamente personalizado, consulte
Tornar visualizações personalizadas mais
acessíveis.
Esta seção descreve como implementar um tipo especial de
Switch
chamado TriSwitch
. Um objeto
TriSwitch
funciona de maneira semelhante a um Switch
, mas cada instância de
TriSwitch
permite que o usuário alterne entre três estados possíveis.
Estender a partir da hierarquia de classes
O objeto Switch
herda de várias classes de IU do framework na hierarquia:
View ↳ TextView ↳ Button ↳ CompoundButton ↳ Switch
É melhor que a nova classe TriSwitch
seja estendida diretamente da classe
Switch
. Dessa forma, o framework de acessibilidade
do Android
oferece a maioria dos recursos necessários para a classe
TriSwitch
:
- Ações de acessibilidade: informam ao sistema como os serviços de acessibilidade
emulam cada entrada do usuário possível realizada em um objeto
TriSwitch
. Configuração herdada deView
. - Eventos de acessibilidade: informam aos serviços de acessibilidade todas as maneiras
possíveis em que a aparência de um objeto
TriSwitch
pode mudar quando a tela é atualizada. Configuração herdada deView
. - Características: detalhes sobre cada objeto
TriSwitch
, como o conteúdo de qualquer texto exibido. Configuração herdada deTextView
. - Informações de estado: uma descrição do estado atual de um objeto
TriSwitch
, como "marcado" ou "desmarcado". Configuração herdada deCompoundButton
. - Descrição em texto do estado: uma explicação escrita do que cada estado
representa. Configuração herdada de
Switch
.
Esse comportamento agregado, de Switch
e das superclasses dele, é praticamente o
comportamento desejado dos objetos TriSwitch
. Portanto, sua implementação pode
se concentrar na expansão do número de estados possíveis de dois para três.
Definir eventos personalizados
Ao estender um widget do sistema, você provavelmente muda um aspecto de como os usuários interagem com esse widget. É importante definir essas mudanças de interação para que os serviços de acessibilidade possam atualizar o widget do app como se o usuário interagisse diretamente com ele.
Uma orientação geral é que, para cada callback baseado em visualização que você substituir,
também precisará redefinir a ação de acessibilidade correspondente modificando
ViewCompat.replaceAccessibilityAction()
.
Nos testes do app, você pode validar o comportamento dessas ações redefinidas
chamando
ViewCompat.performAccessibilityAction()
.
Como esse princípio se aplica a objetos triSwitch
Ao contrário de um objeto Switch
comum, tocar em um objeto TriSwitch
alterna entre
três estados possíveis. Portanto, a ação de acessibilidade ACTION_CLICK
correspondente precisa ser atualizada:
Kotlin
class TriSwitch(context: Context) : Switch(context) { // 0, 1, or 2. var currentState: Int = 0 private set init { updateAccessibilityActions() } private fun updateAccessibilityActions() { ViewCompat.replaceAccessibilityAction(this, ACTION_CLICK, action-label) { view, args -> moveToNextState() }) } private fun moveToNextState() { currentState = (currentState + 1) % 3 } }
Java
public class TriSwitch extends Switch { // 0, 1, or 2. private int currentState; public int getCurrentState() { return currentState; } public TriSwitch() { updateAccessibilityActions(); } private void updateAccessibilityActions() { ViewCompat.replaceAccessibilityAction(this, ACTION_CLICK, action-label, (view, args) -> moveToNextState()); } private void moveToNextState() { currentState = (currentState + 1) % 3; } }
Usar outras indicações além da cor
Para ajudar os usuários com deficiências visuais relacionadas a cores, use outros tipos de indicador para distinguir os elementos da IU nas telas do seu app. Essas técnicas podem incluir o uso de diferentes formas ou tamanhos, disponibilização de texto ou padrões visuais ou adição de retorno tátil baseado em áudio ou toque para marcar as diferenças dos elementos.
A Figura 1 mostra duas versões de uma atividade. Uma versão usa somente cores para diferenciar duas ações possíveis em um fluxo de trabalho. A outra versão usa a prática recomendada de incluir formas e texto, além de cores, para destacar as diferenças entre as duas opções:
Tornar o conteúdo de mídia mais acessível
Se você estiver desenvolvendo um app que inclui conteúdo de mídia, como um trecho de vídeo ou gravação de áudio, faça o possível para ajudar os usuários com diferentes tipos de necessidades de acessibilidade a entender esse material. Em particular, recomendamos que você faça o seguinte:
- Inclua controles que permitam aos usuários pausar ou interromper a mídia, mudar o volume e alternar as legendas.
- Se um vídeo apresentar informações essenciais para a conclusão de um fluxo de trabalho, disponibilize o mesmo conteúdo em um formato alternativo, como uma transcrição.
Outros recursos
Para saber mais sobre como tornar seu app mais acessível, consulte estes recursos extras:
Codelabs
- Acessibilidade básica do Android (em inglês)