TextInputLayout é um componente da biblioteca Material Components para Android que envolve um EditText e adiciona recursos avançados de entrada de texto. A função principal do TextInputLayout é o rótulo flutuante (floating label), que se eleva acima do campo quando o texto é inserido, economizando espaço e melhorando a legibilidade. Além disso, o componente suporta a exibição de mensagens de erro, ícones dentro do campo, um contador de caracteres e vários estilos de formatação. De acordo com as Material Design Guidelines (2025), o TextInputLayout é a maneira recomendada de criar campos de texto em aplicativos Android que estejam em conformidade com os padrões do Material Design 3.
Pontos principais
TextInputLayout é um ViewGroup do pacote com.google.android.material.textfield que estende LinearLayout e contém um EditText internamente. O componente faz parte da biblioteca Material Components para Android, a partir da versão 1.0.0. O principal objetivo do TextInputLayout é fornecer uma implementação pronta dos campos de texto do Material Design com o mínimo esforço do desenvolvedor.
Ao contrário de um EditText padrão, o TextInputLayout gerencia a animação do rótulo flutuante, que é definida através do atributo android:hint do EditText interno. Quando o campo está vazio, o rótulo aparece dentro do campo como uma dica comum. Assim que o usuário começa a digitar, o rótulo se move animadamente para a parte superior do campo, reduzindo de tamanho. De acordo com as Material Design Guidelines (2025), essa animação melhora a percepção do formulário, pois o usuário sempre vê o nome do campo, mesmo após inserir os dados.
Arquiteturalmente, o TextInputLayout implementa o padrão decorador: ele intercepta eventos do EditText, gerencia a exibição de elementos adicionais (rótulo, erro, ícones, contador) e coordena sua animação. O EditText interno é acessível através do método getEditText() e pode ser configurado com atributos padrão, incluindo inputType, maxLines e hint.
<!-- Basic TextInputLayout markup -->
@+id/tilEmail
android:layout_width="match_parent"
android:layout_height="wrap_content">
@+id/etEmail
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Email"
android:inputType="textEmailAddress" />
</com.google.android.material.textfield.TextInputLayout>
O rótulo flutuante (floating label) é o recurso principal do TextInputLayout. Quando o campo está vazio, o texto de android:hint é exibido dentro do EditText como um placeholder comum. Quando o campo recebe foco ou o texto é inserido, o rótulo se eleva para a parte superior do TextInputLayout, reduzindo o tamanho da fonte e mudando de cor. Esse comportamento resolve o problema da dica se tornar invisível depois que o usuário começa a digitar.
A configuração do rótulo flutuante é feita através dos atributos do TextInputLayout: app:hintEnabled determina se o rótulo flutuante está ativado (padrão true), app:hintAnimationEnabled ativa ou desativa a animação de transição, app:expandedHintEnabled permite exibir o rótulo mesmo quando o campo está vazio e sem foco. A cor do rótulo em diferentes estados é gerenciada através dos estilos colorPrimary e colorControlHighlight.
De acordo com o Google Material Components Team (2025), o rótulo flutuante é especialmente útil em formulários com muitos campos, onde o usuário pode esquecer o nome do campo depois de começar a digitar. Ao contrário de um simples android:hint que desaparece na entrada, o rótulo flutuante permanece visível o tempo todo, fornecendo contexto para cada campo.
| Atributo | Descrição | Padrão |
|---|---|---|
| hintEnabled | Ativa ou desativa o rótulo flutuante | true |
| hintAnimationEnabled | Ativa a animação de subida/descida do rótulo | true |
| expandedHintEnabled | Mostra o rótulo mesmo quando o campo está vazio e sem foco | false |
| hintTextAppearance | Estilo do texto do rótulo flutuante | Tema do aplicativo |
TextInputLayout fornece um sistema integrado de exibição de erros que é visualmente integrado ao campo de entrada. Ao definir um erro através do método setError, o componente destaca o campo (a cor da linha ou contorno muda para vermelho) e exibe o texto de erro abaixo do campo. Isso elimina a necessidade de um TextView separado para mensagens de erro.
O gerenciamento da exibição de erros é feito através dos métodos setError(CharSequence) e setErrorEnabled(boolean). Ao chamar setError com texto, o erro é exibido imediatamente; ao chamar setError(null), ele é ocultado. O TextInputLayout também suporta um ícone de erro personalizado através do atributo app:errorIconDrawable e o gerenciamento da cor do erro através de app:errorTextColor.
De acordo com as Material Design Guidelines (2025), as mensagens de erro devem ser específicas e úteis: em vez de “Entrada inválida” escreva “O email deve conter @”. A exibição do erro deve ocorrer após a conclusão da entrada (na perda de foco ou após o envio do formulário), não em tempo real — isso reduz o estresse do usuário ao preencher formulários.
// Configuração programática de erros
textInputLayout.error = "Password min 8 chars"
// Ocultação de erros
textInputLayout.error = null
// Verificação e definição de erros de validação
if (email.isNullOrBlank()) {
tilEmail.error = "Email is required"
} else {
tilEmail.error = null
}
TextInputLayout suporta a exibição de ícones tanto no início do campo (start icon) quanto no final (end icon). Os ícones podem executar várias funções: alternar a visibilidade da senha, limpar o campo, ações personalizadas. Cada tipo de ícone é controlado por um atributo separado e pode ser substituído por um personalizado através do atributo app:startIconDrawable ou app:endIconDrawable.
O modo de ícone final é definido através do atributo app:endIconMode, que pode assumir os seguintes valores: password_toggle — alternância de visibilidade da senha, clear_text — limpeza do campo, dropdown_menu — seta para lista suspensa, custom — ícone personalizado. Para password_toggle, o TextInputLayout gerencia automaticamente a alternância do inputType entre textPassword e textVisiblePassword, e também anima o ícone do olho.
<!-- TextInputLayout with password toggle icon -->
@+id/tilPassword
android:layout_width="match_parent"
app:endIconMode="password_toggle"
app:passwordToggleTint="@color/primary">
@+id/etPassword
android:inputType="textPassword" />
</com.google.android.material.textfield.TextInputLayout>
O Material Components para Android fornece dois estilos principais para TextInputLayout: FilledBox (preenchido) e OutlinedBox (com contorno). O estilo FilledBox tem um fundo preenchido com cor e uma linha abaixo do campo que muda de cor ao receber foco. O estilo OutlinedBox tem um fundo transparente e um contorno ao redor de todo o campo, criando limites mais claros e sendo mais adequado para formulários com muitos campos.
A escolha do estilo depende do design do aplicativo: FilledBox é recomendado para formulários de uso frequente, pois atrai menos atenção para campos individuais. OutlinedBox é preferível para formulários curtos (login, registro) onde cada campo deve estar claramente marcado. O estilo é definido através do atributo style no XML ou através do tema do aplicativo.
| Característica | FilledBox | OutlinedBox |
|---|---|---|
| Fundo | Preenchimento com cor (geralmente cinza) | Transparente |
| Borda | Linha na parte inferior | Contorno ao redor do campo |
| Foco | A linha engrossa e muda de cor | O contorno muda de cor e engrossa |
| Recomendação | Formulários com entrada frequente | Formulários curtos, ênfase nos campos |
| Estilo | Widget.MaterialComponents.TextInputLayout.FilledBox | Widget.MaterialComponents.TextInputLayout.OutlinedBox |
O Material Design 3 (M3) introduziu estilos atualizados para TextInputLayout com tipografia melhorada, novos tokens de cor e suporte para cores dinâmicas do Material You. No M3, o OutlinedBox se tornou o estilo recomendado por padrão, e o FilledBox adaptou seu preenchimento e raio de borda para atender à nova especificação.
Um exemplo completo de implementação de um formulário de registro com TextInputLayout, incluindo validação de email e senha, exibição de erros e ícone de mostrar senha. Ao pressionar o botão de registro, todos os campos são verificados e as mensagens de erro correspondentes são exibidas.
@+id/tilName
app:boxBackgroundMode="outlined">
@+id/etName
android:hint="Name" />
</...TextInputLayout>
@+id/tilRegEmail
app:boxBackgroundMode="outlined">
@+id/etRegEmail
android:hint="Email"
android:inputType="textEmailAddress" />
</...TextInputLayout>
@+id/tilRegPassword
app:boxBackgroundMode="outlined"
app:endIconMode="password_toggle">
@+id/etRegPassword
android:hint="Password"
android:inputType="textPassword" />
</...TextInputLayout>
private fun validateForm(): Boolean {
var isValid = true
if (etName.text.isNullOrBlank()) {
tilName.error = "Enter your name"
isValid = false
} else {
tilName.error = null
}
val email = etRegEmail.text.toString()
if (!Patterns.EMAIL_ADDRESS.matcher(email).matches()) {
tilRegEmail.error = "Invalid email format"
isValid = false
} else {
tilRegEmail.error = null
}
val password = etRegPassword.text.toString()
if (password.length < 8) {
tilRegPassword.error = "Password min 8 chars"
isValid = false
} else {
tilRegPassword.error = null
}
return isValid
}
Perguntas frequentes
TextInputLayout está disponível a partir da versão 1.0.0 da biblioteca com.google.android.material. Para recursos do Material Design 3, use a versão 1.6.0 ou superior. Inclua: implementation “com.google.android.material:material:1.12.0” no build.gradle do módulo.
A cor do rótulo flutuante no estado de foco é controlada pelo atributo app:hintTextColor ou através do tema usando colorPrimary. Para diferentes estados (foco, erro, desativado), use um seletor em res/color/ ou os atributos boxStrokeColor, errorTextColor da biblioteca Material Components.
Defina o atributo app:counterEnabled=“true” e especifique o número máximo de caracteres com app:counterMaxLength=“100”. O TextInputLayout exibirá automaticamente o contador na parte inferior do campo (por exemplo, “25/100”). A cor do contador pode ser configurada através de app:counterTextColor e app:counterOverflowTextColor para quando o limite é excedido.
FilledBox — fundo preenchido com cor, ênfase na linha inferior. Ocupa menos espaço visual. OutlinedBox — fundo transparente com contorno ao redor do campo, bordas mais visíveis. FilledBox é recomendado para campos de uso frequente, OutlinedBox para formulários curtos onde a clareza de cada campo é importante.
Sim, defina o atributo app:hintEnabled=“false” para desativar o rótulo flutuante. Nesse caso, o TextInputLayout funcionará como um invólucro normal para EditText, mantendo a funcionalidade de erros, ícones e contador de caracteres, mas sem a animação do rótulo. Útil para campos onde uma dica não é necessária ou um rótulo personalizado é usado.
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