Todos já vimos em algum formulário em apps ou sites aquele campo que diz “Li e concordo com os termos de uso [blá blá blá]”, mas você já percebeu que em alguns casos você pode clicar em partes do texto e ele irá abrir os termos de uso em questão?

Note que existem partes do texto em azul, mostrando que elas servem como links para algum recurso.
Esse é o assunto desse artigo. Aprenda a desenvolver esse recurso em seu app Android!
Para criar esse recurso podemos utilizar uma SpannableString, uma classe de texto personalizável do Android. Essa classe nos permite adicionar elementos visuais e funcionais à strings, exatamente o que precisamos.
Formulando o problema
Vamos descrever os dados necessários. Temos um certo texto, e temos um trecho do mesmo texto que precisa ter uma cor e uma função onClick. Com isso, podemos criar o esqueleto do nosso método
fun criarLink(
textoCompleto: String,
parteTextoClicavel: String,
textoClicavelCor: Int,
onClick: View.OnClickListener
): SpannableString {
val spannableString = SpannableString(textoCompleto)
return spannableString
}
Agora que temos nosso esqueleto da função, vamos para a próxima etapa.
Criando a parte clicavel
Para que um Spannable aceite clicks, utilizaremos a classe ClickableSpan:
val clickableSpan = object : ClickableSpan() {
override fun updateDrawState(ds: TextPaint) {
ds.color = textoClicavelCor
ds.isUnderlineText = true //mude para false caso não queira sublinhar
}
override fun onClick(view: View) {
onClick.onClick(view)
}
}
Agora precisamos adicionar isso ao nosso SpannableString, indicando a parte que precisa receber esse elemento de clique:
val inicio = textoCompleto.indexOf(parteTextoClicavel)
val fim = inicio + parteTextoClicavel.length
spannableString.setSpan(
clickableSpan,
inicio,
fim,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
)
Clique no TextView
Para que o TextView aceite clicks corretamente, precisamos configurar a propriedade movementMethod. Essa propriedade indica a quem o textView deve delegar o evento de clique. Nesse caso, devemos utilizar LinkMovementMethod.getInstance(), como demonstraremos a seguir.
Finalização
Após essas etapas, devemos ter a seguinte função:
fun criarLink(
textoCompleto: String,
parteTextoClicavel: String,
textoClicavelCor: Int,
onClick: View.OnClickListener
): SpannableString {
val spannableString = SpannableString(textoCompleto)
val clickableSpan = object : ClickableSpan() {
override fun updateDrawState(ds: TextPaint) {
ds.color = textoClicavelCor
ds.isUnderlineText = true
}
override fun onClick(view: View) {
onClick.onClick(view)
}
}
val inicio = textoCompleto.indexOf(parteTextoClicavel)
val fim = inicio + parteTextoClicavel.length
spannableString.setSpan(
clickableSpan,
inicio,
fim,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
)
return spannableString
}
E para a utilizarmos em nosso TextView:
//criando link de termos de uso
val linkTermo = criarLink(
"Ao enviar os dados, você concorda com o termo de uso do serviço",
"termo de uso do serviço",
Color.BLUE
) {
val uri = Uri.parse( "https://www.seusite.com.br/termosdeuso" )
val intent = Intent( Intent.ACTION_VIEW, uri )
startActivity( intent )
}
//criando link de politica de privacidade
val linkPolitica = criarLink(
" e nossa política de privacidade",
"nossa política de privacidade",
Color.BLUE
) {
val uri = Uri.parse( "https://www.seusite.com.br/politicadeprivacidade" )
val intent = Intent( Intent.ACTION_VIEW, uri )
startActivity( intent )
}
binding.textViewLinks.movementMethod = LinkMovementMethod.getInstance() //Passando o movementMethod para que os links funcionem corretamente
binding.textViewLinks.setText( TextUtils.concat(linkTermo, linkPolitica) , TextView.BufferType.SPANNABLE) //Passando o texto personalizado
Resultados

Conclusão
Nesse artigo vimos como é simples integrar links clicáveis em um TextView no Android!