Acessibilidade com Jetpack Compose

Relato de experiência ao aplicar recursos de acessibilidade do Jetpack Compose em um projeto pessoal.

Gabriel Bronzatti Moro
Android Dev BR
5 min readNov 30, 2022

--

É preciso falar sobre acessibilidade, principalmente no cenário de desenvolvimento de aplicativos. Cada vez mais as pessoas dependem de aplicativos para realizar tarefas comuns do dia-a-dia, mas será que todas as pessoas conseguem usufruir de todos os recursos que um aplicativo oferece?

Segundo o IBGE, em uma pesquisa nacional, no Brasil, cerca de 17,3 milhões de pessoas a cima de 2 anos possuem algum tipo de deficiência. O que representa 8,4% da população brasileira. Nesse grupo 24,8% são idosos e 75,2% não são idosos. E no seu aplicativo:

  • Qual é a porcentagem de usuários que possuem algum tipo de deficiência ou alguma dificuldade relacionada ao uso do aplicativo?
  • Quantos usuários deixam de utilizar o seu aplicativo por não ser acessível?

Pode ser muito mais do que 8,4% 😢

Em agosto de 2020 foi anunciado a versão alpha do Jetpack Compose, um novo jeito de construir interfaces gráficas no Android, desde lá o toolkit vem evoluindo e sendo adotado cada vez mais por desenvolvedores. Mas quais os recursos de acessibilidade o Jetpack Compose oferece?

Nesse artigo vou apresentar alguns recursos que pude utilizar no meu projeto pessoal para auxiliar o leitor de telas do Android.

Elementos Clicáveis

Os elementos clicáveis devem possuir um tamanho mínimo de 48dp (guidelines), menor do que esse tamanho pode dificultar a vida do usuário. Devemos garatir que o elemento clicável seja grande o suficiente para ser utilizado pelo usuário. Para refletir, a seguir temos uma ilustração de Homer Simpson tentando clicar nos botões pequenos

Homer Simpson with his smartphone

As guidelines de acessibilidade são seguidas a risca pelos elementos base providos pelo próprio Compose:

Componente FloatingActionButton do Compose. Nele está destacado o FabSize e o ExtendedFabSize, 56.dp e 48.dp respectivamente. Essas duas dimensões estão respeitando o guia de acessibilidade.
Componente FloatingActionButton

A seguir temos uma tela do aplicativo SimpleMath (projeto pessoal) e a seção de quizzes em destaque. Vamos focar no evento de clique para acessar um quiz.

Tela de jogos do aplicativo pessoal. Nessa tela tem uma seção aonde é possível selecionar quizzes para jogar. O quizzes disponíveis nessa tela são de Probabilidade e Adição e subtração.
Aba de Jogos do SimpleMath.

Cada card possui o seguinte código:

O Talkback descreverá o card da seguinte forma: “Probabilidade. Moro. Tocar duas vezes para ativar”. Essa descrição não auxilia muito o usuário, podemos melhorar da seguinte forma:

Com as novas propriedades role e onClickLabel , o Talkback descreverá: “Probabilidade, Moro. Botão. Tocar duas vezes para Acessar.

Elementos de Alternância

Na tela a seguir temos um componente no qual o usuário pode selecionar uma resposta:

Três opções de respostas para determinado quiz, dentre elas: 5, 4 e 6. O componente 5 está selecionado, pois o Talkback está descrevendo ele.
Componente de respostas.

Esse componente utiliza o seguinte modifier:

O Talkback descreve esse elemento da seguinte maneira: “Não selecionado. 5. Botão de opção. Tocar duas vezes para alternar.”

Caso o usuário selecione a resposta, o aplicativo marcará como resposta certa ou errada:

Três opções de respostas para determinado quiz, dentre elas: 5, 4 e 6. O componente 5 está com o estado de resposta correta e está selecionado pois o Talkback está descrevendo ele.
Componente de respostas com resposta correta.

Como ajudar o Talkback informando o estado do botão?

A gente precisa dizer ao leitor de telas que a resposta está certa (verde) ou errada (vermelho). Uma das formas de alcançar isso é utilizando a stateDescription. Assim o modifier ficará:

Após o usuário selecionar a resposta, o Talkback descreverá: “Resposta correta” ou “Resposta errada”, dependendo do stateDescription.

Descrição de conteúdo

Na tela abaixo, temos um componente para indicar ao usuário a página aonde ele se encontra, assim é possível ter uma noção de quanto falta para terminar o quiz.

Essa tela retirada do aplicativo possui um indicador de páginas, aonde o usuário se encontra na segunda página.
Tela de questão com o componente indicador de página atual selecionado.

Esse componente foi criado de forma customizada, utilizando Canvas :

O Talkback terá problemas para ler esse componente, pois ele não possui nenhuma propriedade semântica. Podemos ajudar o Talkback adicionando o seguinte contentDescription :

Assim, o Talkback descreverá da seguinte forma: “De 4 páginas, você está na página de número 1”. Outro fato interessante aqui é o uso da propriedade mergeDescendants para dizer ao Talkback agrupar todo o conteúdo do Row em uma mesma descrição.

As vezes recebemos informações do servidor em um formato e exibimos em outro formato. Esse é o caso do componente de texto a seguir:

Tela apresenta uma questão aonde o usuário é perguntado se 1 sobre 2 pode ser considerado 50% em probabilidade. Dentre as opções de resposta, nós temos Sim ou Não.
Tela de questão com o componente de questão selecionado.

Nessa tela, o servidor está enviando o seguinte texto: “1- — — 2 pode ser considerado 50% em probabilidade?”. Com isso, o Talkback descreverá algo diferente da representação visual do texto, o usuário que depende do Talkback não compreenderá que é uma fração 😢. Mais uma vez, a semantics nos auxiliará:

Podemos substituir o“1- — — 2 pode ser considerado 50% em probabilidade?” por 1 sobre 2 pode ser considerado 50% em probabilidade?”. Nesse caso, o Talkback considera como valor de texto o informado pelo text dosemantics.

Mescla de elementos

Ao finalizar um quiz, o usuário acessa uma tela de resultados no aplicativo:

Tela apresentada ao final do preenchimento do quiz, informando o resultado das tentativas do usuário. Nesse caso, o usuário acertou apenas 1 questão de 4. O conselho dado ao usuário é “Quase lá”.
Tela de resultados do quiz com o componente de performance selecionado.

Nesse caso, o Talkback consegue ler da seguinte forma “Total de acertos. 1. Número de questões 4.” Mas podemos melhorar da seguinte forma:

Utilizando clearAndSetSemantics , todo valor semântico do nó é redefinido, assim conseguimos garantir um novo valor a ser interpretado pelo Talkback. O contentDescription será lido pelo Talkback da seguinte forma: “De 1 questão, você acertou 2”.

💡Dicas

Conclusão

Garantir que o usuário consiga ter uma boa experiência de uso é algo vital para o sucesso de qualquer aplicativo. O conceito de acessibilidade permite ampliar o alcance de qualquer produto, proporcionando que todos os usuários possam se beneficiar 🤗.

Ótima definição retirada do livro The Center for Universal Design: The Principles of Universal Design, que diz:

Desenho universal é design de produtos e ambientes para ser utilizado por todas as pessoas, na maior medida possível, sem a necessidade de adaptação ou design especializado.

Mesma escada na qual todas as pessoas possam utilizar. Ela permite que pessoas de cadeira de rodas, pessoas com dificuldades de locomoção também possam utilizar.
Escada acessível.

--

--