Kotlin Acessível: código que não abandona usuários

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Por que acessibilidade em Kotlin é um superpoder, não uma formalidade

\n\n

Imagine: você criou um aplicativo incrível em Kotlin. Material Design bonito, animações suaves, streams reativos. Você se orgulha do código. Mas descobre que uma pessoa com baixa visão não consegue apertar o botão "Comprar" porque o TalkBack lê como "botão não identificado". Ou um usuário com tremor nas mãos erra o minúsculo interruptor.

\n\n

Acessibilidade não é burocracia chata. É fazer seu código em Kotlin funcionar para todos. Segundo a OMS, mais de um bilhão de pessoas têm alguma deficiência. Ignorá-las é perder público e, francamente, ser um desenvolvedor ruim.

\n\n

Neste artigo, vamos ver como escrever código acessível em Kotlin sem dor de cabeça. Sem toneladas de código repetitivo. Com exemplos práticos que você pode copiar e colar agora mesmo.

\n\n

Princípios básicos: ContentDescription é seu melhor amigo

\n\n

A falha mais comum em acessibilidade é a falta de descrição para elementos da interface. O TalkBack (leitor de tela do Android) não lê imagens ou ícones. Ele precisa de texto.

\n\n

Em Kotlin, isso é feito com o atributo contentDescription. Mas não apenas "Botão", e sim algo com significado.

\n\n

Exemplo ruim (não faça isso)

\n
imageView.contentDescription = "Botão"
\n\n

Exemplo bom

\n
binding.fabAddTask.contentDescription = "Adicionar nova tarefa"
\n\n

Se o ícone for decorativo (apenas enfeite) — defina contentDescription = null para o TalkBack ignorá-lo.

\n\n
// Ícone decorativo — não distraia o usuário\nbinding.decorativeIcon.contentDescription = null
\n\n

Dica: Use recursos de string (strings.xml) para suportar localização. Não coloque texto fixo em português nos arquivos Kotlin.

\n\n

Marcação semântica: dizendo ao sistema o que é importante

\n\n

As View padrão (Button, TextView) funcionam bem, mas componentes personalizados frequentemente quebram a acessibilidade. Em Kotlin, podemos definir a semântica explicitamente.

\n\n

Adicionando um papel ao elemento

\n
binding.customView.importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_YES\nbinding.customView.accessibilityDelegate = object : View.AccessibilityDelegate() {\n    override fun onInitializeAccessibilityNodeInfo(host: View, info: AccessibilityNodeInfo) {\n        super.onInitializeAccessibilityNodeInfo(host, info)\n        info.text = "Valor atual: ${viewModel.value}"\n        info.contentDescription = "Slider de volume"\n    }\n}
\n\n

Esse código diz ao sistema: "Ei, isso não é um quadrado, é um slider!". O TalkBack entenderá que o elemento é interativo e poderá interagir corretamente.

\n\n

Agrupando elementos

\n

Se você tem um card de produto com imagem, preço e nome — agrupe-os em um único foco. Caso contrário, o usuário ouvirá três elementos separadamente.

\n\n
binding.cardProduct.apply {\n    isFocusable = true\n    contentDescription = "Produto: ${product.name}, preço: ${product.price} reais"\n}
\n\n

Agora o TalkBack lê todas as informações em um único toque.

\n\n

Navegação por ação: teclado e D-pad

\n\n

Nem todos os usuários tocam na tela. Alguns usam teclado (via OTG) ou D-pad (controle remoto). Seu aplicativo deve ser navegável sem toques.

\n\n

Em Kotlin, isso é resolvido com focusable e a ordem de foco (nextFocusDown, nextFocusForward).

\n\n
binding.buttonNext.nextFocusForwardId = R.id.buttonConfirm\nbinding.buttonConfirm.nextFocusDownId = R.id.buttonCancel
\n\n

Verifique se todos os elementos interativos recebem foco. Um erro comum é TextView com ClickableSpan (link no texto). Por padrão, ele não recebe foco. Corrigimos:

\n\n
binding.textWithLink.movementMethod = LinkMovement                

Blogs

Book Recommendations