InputFilter é uma interface do Android SDK que permite interceptar e modificar o texto digitado antes de sua exibição no EditText. O desenvolvedor define regras de filtragem: caracteres permitidos, comprimento máximo, formato de entrada. De acordo com Android Developers, 2026, o InputFilter é usado para restringir a entrada de letras, dígitos, caracteres especiais e formatação automática de texto. Ao contrário do TextWatcher, o filtro é acionado antes da alteração do texto, evitando entrada inválida no nível da origem.
Pontos principais
InputFilter é uma interface funcional do pacote android.text que define um único método filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend). Ele é chamado automaticamente sempre que o usuário tenta digitar, colar ou substituir texto no EditText. O valor retornado determina se a alteração será aceita, rejeitada ou modificada.
O principal propósito do InputFilter é prevenir entrada inválida antes que o texto entre no campo. Por exemplo, em um campo de dígitos de número de telefone, um filtro pode bloquear letras e caracteres especiais. Em um campo de senha, pode exigir um comprimento mínimo. Em um campo de código de verificação, pode permitir apenas dígitos. Ao contrário da validação via TextWatcher, o filtro impede que caracteres errôneos apareçam na tela.
De acordo com o Android Developers, o InputFilter é usado em todos os componentes do Material Design para TextInputEditText. Bibliotecas como PhoneNumberFormattingTextWatcher combinam TextWatcher e InputFilter para formatação completa. Recomenda-se usar InputFilter como primeira barreira de proteção contra entrada inválida e TextWatcher para lógica adicional pós-entrada.
O método filter recebe seis parâmetros: source — o texto de entrada, start e end — os limites do fragmento de entrada, dest — o conteúdo atual do campo, dstart e dend — a posição de inserção. Se o método retornar null, a alteração é aceita sem modificações. Se retornar uma string vazia “”, a alteração é bloqueada. Se retornar uma nova CharSequence, o texto original é substituído pelo valor retornado.
Por exemplo, se um usuário tentar digitar a letra “a” em um campo que permite apenas dígitos, o filtro retorna “” e o caractere não aparece. Se “123” for inserido, o filtro pode retornar “1-2-3”, adicionando separadores. Esse mecanismo permite formatação automática de números de telefone, datas e outros dados estruturados sem TextWatcher.
Importante: o InputFilter não modifica a fonte de dados original, apenas retorna uma versão filtrada. O próprio Android aplica o valor retornado ao Editable. Se o filtro retornar null, nenhuma ação adicional é necessária. Se retornar texto modificado, o Android remove o intervalo original e insere o novo.
O Android SDK fornece várias implementações integradas do InputFilter. A mais comum é o InputFilter.LengthFilter, que limita o comprimento máximo do texto. O construtor aceita um número inteiro — o número máximo de caracteres. Se o comprimento atual do texto mais a entrada exceder o limite, o filtro retorna uma string truncada, impedindo que o limite seja ultrapassado.
Também está disponível o InputFilter.AllCaps, que converte todos os caracteres inseridos para maiúsculas. É usado em campos para códigos, códigos postais e outros dados onde maiúsculas/minúsculas importam. O filtro não apenas bloqueia minúsculas, mas as converte, o que é conveniente para o usuário — ele vê o resultado da conversão.
Existe o InputFilter.LengthFilter para múltiplos limites — através de uma combinação de filtros. Por exemplo, se você precisa limitar o comprimento a 20 caracteres e permitir apenas dígitos, pode aplicar LengthFilter + um filtro de dígitos personalizado. Cada filtro executa sequencialmente, e o resultado do anterior torna-se o dest para o próximo.
| Filtro | Objetivo | Exemplo de uso |
|---|---|---|
| LengthFilter | Restrição de comprimento | Campo de nome até 50 caracteres |
| AllCaps | Conversão para maiúsculas | Campo de código postal |
| InputFilter personalizado | Regras de filtragem arbitrárias | Apenas dígitos, sem caracteres especiais |
Para criar um filtro personalizado, você precisa implementar a interface InputFilter e sobrescrever o método filter. Uma tarefa comum é um filtro que permite apenas dígitos. Neste caso, o método verifica cada caractere do source usando Character.isDigit e retorna uma string filtrada ou null se todos os caracteres forem válidos.
class DigitsInputFilter : InputFilter {
override fun filter(
source: CharSequence?,
start: Int,
end: Int,
dest: Spanned?,
dstart: Int,
dend: Int
): CharSequence? {
val sb = StringBuilder()
for (i in start until end) {
val c = source?.get(i)
if (c != null && Character.isDigit(c)) {
sb.append(c)
}
}
return if (sb.length == end - start) null else sb
}
}
Um exemplo DigitsInputFilter percorre todos os caracteres do texto de entrada e mantém apenas os dígitos. Se todos os caracteres passarem na verificação, o método retorna null — este é o caso ideal, pois não requer operações adicionais de memória. Se alguns caracteres forem descartados, uma nova string é retornada e apenas dígitos chegam ao EditText.
Outro cenário popular é um filtro para bloquear caracteres especiais. A implementação é semelhante: verificar cada caractere via Character.isLetterOrDigit ou comparar com uma lista de caracteres permitidos. Esses filtros são usados em campos de nome de usuário, strings de pesquisa e outros lugares onde caracteres especiais não são permitidos.
Os filtros são definidos no EditText através do método setFilters(InputFilter[]). O array de filtros substitui os atuais, portanto, se você precisar adicionar um filtro aos existentes, deve obter os filtros atuais via getFilters(), criar um novo array e defini-lo novamente. O EditText tem um filtro padrão — LengthFilter, que é definido via android:maxLength no XML.
val editText = findViewById<EditText>(R.id.phone_input)
editText.filters = arrayOf(
DigitsInputFilter(),
InputFilter.LengthFilter(10)
)
No exemplo, dois filtros são definidos: DigitsInputFilter (apenas dígitos) e LengthFilter (máximo 10 caracteres). A ordem dos filtros no array é importante: o primeiro filtro recebe a entrada original, processa e passa o resultado para o segundo. Se o DigitsInputFilter filtrar alguns caracteres, o LengthFilter vê o texto já filtrado e aplica sua restrição de comprimento a ele.
Os filtros também podem ser definidos através do atributo XML android:inputType, que adiciona automaticamente alguns filtros. Por exemplo, inputType=“phone” adiciona DigitsKeyListener e permite apenas dígitos e alguns caracteres especiais. No entanto, para controle total sobre a filtragem, recomenda-se usar setFilters programaticamente, especialmente ao combinar várias regras.
InputFilter e TextWatcher desempenham funções diferentes e frequentemente são usados juntos. O InputFilter trabalha no nível de entrada — impede que caracteres inválidos entrem no campo. O TextWatcher trabalha após a entrada — permite reagir a alterações, realizar validação de regras complexas e atualizar a interface do usuário. A combinação de ambas as abordagens oferece o melhor resultado.
Por exemplo, para um campo de entrada de e-mail: o InputFilter pode bloquear espaços e caracteres cirílicos no nível de entrada, enquanto o TextWatcher pode verificar a conformidade total com o padrão de e-mail após cada alteração. O primeiro protege contra erros óbvios, o segundo contra erros estruturais. Essa separação de responsabilidades torna o código mais limpo e reduz a carga de validação.
De acordo com as Material Design Guidelines, os filtros devem ser aplicados a campos com restrições estritas: números de telefone, códigos de verificação, PINs, códigos postais. Para campos com validação flexível — nome, endereço, comentário — apenas o TextWatcher é suficiente para não impedir que usuários insiram valores legítimos, mas não padronizados.
| Critério | InputFilter | TextWatcher |
|---|---|---|
| Momento de ativação | Antes da alteração do texto | Após a alteração do texto |
| Objetivo | Bloquear caracteres inválidos | Reagir a alterações, validação, UI |
| Valor de retorno | Texto filtrado ou null | Nenhum (void) |
| Aplicação | setFilters() | addTextChangedListener() |
Perguntas frequentes
InputFilter intercepta a entrada antes da alteração do texto e pode bloqueá-la ou modificá-la. O TextWatcher é chamado após a alteração e permite reagir ao novo valor. InputFilter é proteção preventiva, TextWatcher é pós-processamento. Para validação completa de formulário, recomenda-se usar ambas as abordagens.
Passe um array de filtros ao método setFilters(). Os filtros executam sequencialmente na ordem do array. Para não perder filtros existentes, obtenha-os via getFilters(), adicione novos a uma cópia do array e o defina novamente via setFilters. Não sobrescreva filtros sem considerar os já instalados.
Sim, o InputFilter pode modificar a entrada retornando uma CharSequence modificada. Por exemplo, um filtro para número de telefone pode adicionar espaços ou parênteses. No entanto, para formatação complexa, é melhor combinar InputFilter com TextWatcher, já que o filtro é focado em bloqueio, não em pós-processamento.
Qualquer caractere: espaços, letras, dígitos, caracteres especiais, caracteres Unicode. Em um filtro personalizado, você define a condição usando Character.isLetter, isDigit, isWhitespace ou compara com uma lista negra/branca. O filtro pode permitir apenas latim, apenas cirílico ou apenas um conjunto específico de caracteres.
Não, o InputFilter é acionado apenas na entrada do usuário ou ao colar da área de transferência. Se o texto for definido programaticamente via setText(), os filtros não são aplicados. Para verificar texto programático, use validação via TextWatcher ou verificações explícitas antes de definir.
Resumo
Vamos desenvolver um aplicativo móvel chave na mão
A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.
Leia também