Processar entrada do usuário

O TextField permite que os usuários digitem e modifiquem textos. Nesta página, descrevemos como implementar TextField, estilizar a entrada TextField e configurar outras opções de TextField, como opções de teclado e que transformam visualmente a entrada do usuário.

Escolha a implementação de TextField

Há dois níveis de implementação de TextField:

  1. TextField é a implementação do Material Design. Recomendamos que você escolha essa implementação seguindo as diretrizes do Material Design (link em inglês):
    • O estilo padrão é sólido
    • OutlinedTextField é a versão de estilo delineado.
  2. BasicTextField permite que os usuários editem o texto usando o teclado de hardware ou de software, mas não fornece decorações como dicas ou marcadores de posição.

@Composable
fun SimpleFilledTextFieldSample() {
    var text by remember { mutableStateOf("Hello") }

    TextField(
        value = text,
        onValueChange = { text = it },
        label = { Text("Label") }
    )
}

Um campo de texto editável contendo a palavra

@Composable
fun SimpleOutlinedTextFieldSample() {
    var text by remember { mutableStateOf("") }

    OutlinedTextField(
        value = text,
        onValueChange = { text = it },
        label = { Text("Label") }
    )
}

Campo de texto editável com borda e marcador roxos.

Estilo TextField

TextField e BasicTextField têm vários parâmetros em comum para personalização. A lista completa do TextField está disponível no código-fonte do TextField. Veja uma lista não exaustiva de alguns parâmetros úteis:

  • singleLine
  • maxLines
  • textStyle

@Composable
fun StyledTextField() {
    var value by remember { mutableStateOf("Hello\nWorld\nInvisible") }

    TextField(
        value = value,
        onValueChange = { value = it },
        label = { Text("Enter text") },
        maxLines = 2,
        textStyle = TextStyle(color = Color.Blue, fontWeight = FontWeight.Bold),
        modifier = Modifier.padding(20.dp)
    )
}

Um TextField multilinha, com duas linhas editáveis e um marcador

Recomendamos TextField em vez de BasicTextField quando seu design chama um TextField ou OutlineTextField do Material Design. No entanto, o BasicTextField precisa ser usado ao criar designs que não precisam das decorações da especificação do Material Design.

Entrada de estilo com a API Brush

Você pode usar a API Brush para ter um estilo mais avançado no TextField. A seção a seguir descreve como usar um pincel para adicionar um gradiente colorido à entrada TextField.

Para mais informações sobre como usar a API Brush para definir o estilo de texto, consulte Ativar o estilo avançado com a API Brush.

Implementar gradientes coloridos usando TextStyle.

Para implementar um gradiente colorido enquanto você digita em uma TextField, defina o pincel de sua preferência como um TextStyle para a TextField. Nesse exemplo, usamos um pincel integrado com um linearGradient para visualizar o efeito de gradiente do arco-íris à medida que o texto é digitado na TextField.

var text by remember { mutableStateOf("") }
val brush = remember {
    Brush.linearGradient(
        colors = rainbowColors
    )
}
TextField(
    value = text, onValueChange = { text = it }, textStyle = TextStyle(brush = brush)
)

Uso de buildannotatedString e SpanStyle, junto com linearGradient, para personalizar apenas um trecho de texto
Figura 3. Como usar buildAnnotatedString, SpanStyle e linearGradient para personalizar apenas um trecho de texto.

Definir opções do teclado

O TextField permite definir opções de configuração do teclado, como o layout dele, ou ativar a correção automática, caso haja suporte. Algumas opções podem não ser garantidas se o teclado de software não estiver de acordo com as opções apresentadas aqui. Veja a lista de opções de teclado com suporte:

  • capitalization
  • autoCorrect
  • keyboardType
  • imeAction

Formatar entrada

O TextField permite definir uma VisualTransformation no valor de entrada, como substituir caracteres por * para senhas ou inserir hifens a cada quatro (4) dígitos em número de cartão de crédito:

@Composable
fun PasswordTextField() {
    var password by rememberSaveable { mutableStateOf("") }

    TextField(
        value = password,
        onValueChange = { password = it },
        label = { Text("Enter password") },
        visualTransformation = PasswordVisualTransformation(),
        keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password)
    )
}

Campo de entrada de senha com o texto mascarado.

Mais exemplos estão disponíveis no código-fonte de VisualTransformationSamples.

Limpar entrada

Uma tarefa comum ao editar o texto é remover os caracteres iniciais ou transformar a string de entrada sempre que ela mudar.

Como modelo, suponha que o teclado possa fazer edições grandes e arbitrárias em cada onValueChange. Isso pode acontecer, por exemplo, se o usuário usar a correção automática, substituir uma palavra por um emoji ou usar outros recursos de edição inteligentes. Para processar a ação corretamente, programe qualquer lógica de transformação com o pressuposto de que o texto atual transmitido para o método onValueChange não está relacionado aos valores anteriores ou aos próximos que vão ser transmitidos para onValueChange.

Para implementar um campo de texto que não aceita zeros à esquerda, remova todos esses zeros sempre que o valor mudar.

@Composable
fun NoLeadingZeroes() {
    var input by rememberSaveable { mutableStateOf("") }
    TextField(
        value = input,
        onValueChange = { newText ->
            input = newText.trimStart { it == '0' }
        }
    )
}

Para controlar a posição do cursor ao limpar o texto, use a sobrecarga TextFieldValue da função TextField como parte do estado.

Práticas recomendadas com estado

Confira a seguir uma série de práticas recomendadas para definir e atualizar o estado da TextField e evitar problemas de entrada no app.

  • Use MutableState para representar o estado TextField: evite usar fluxos reativos, como StateFlow, para representar o estado TextField, já que essas estruturas podem introduzir atrasos assíncronos.

class SignUpViewModel : ViewModel() {

    var username by mutableStateOf("")
        private set

    /* ... */
}

  • Evite atrasos para atualizar o estado: ao chamar onValueChange, atualize o TextField de forma síncrona e imediata:

// SignUpViewModel.kt

class SignUpViewModel(private val userRepository: UserRepository) : ViewModel() {

    var username by mutableStateOf("")
        private set

    fun updateUsername(input: String) {
        username = input
    }
}

// SignUpScreen.kt

@Composable
fun SignUpScreen(/*...*/) {

    OutlinedTextField(
        value = viewModel.username,
        onValueChange = { username -> viewModel.updateUsername(username) }
        /*...*/
    )
}

  • Onde definir o estado: se o estado TextField exigir validações da lógica de negócios enquanto você digita, é correto elevar o estado para seu ViewModel. Caso contrário, você pode usar elementos combináveis ou uma classe detentora de estado como fonte da verdade. Para saber mais sobre onde elevar o estado, consulte a documentação sobre elevação de estado.