Gestisci l'input utente

TextField consente agli utenti di inserire e modificare testo. In questa pagina viene descritto come implementare l'input TextField, applicare uno stile all'input TextField e configurare altre opzioni di TextField, ad esempio le opzioni della tastiera e la trasformazione visiva dell'input utente.

Scegli l'implementazione TextField

Ci sono due livelli di implementazione di TextField:

  1. TextField è l'implementazione di Material Design. Ti consigliamo di scegliere questa implementazione seguendo le linee guida di Material Design:
    • Lo stile predefinito è compilato
    • OutlinedTextField è la versione per lo stile outline
  2. BasicTextField consente agli utenti di modificare il testo tramite tastiera hardware o software, ma non fornisce decorazioni come suggerimenti o segnaposto.

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

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

Un campo di testo modificabile contenente la parola

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

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

Un campo di testo modificabile con un'etichetta e un bordo viola.

Stile TextField

TextField e BasicTextField condividono molti parametri comuni per la personalizzazione. L'elenco completo per TextField è disponibile nel codice sorgente di TextField. Di seguito è riportato un elenco non esaustivo di alcuni dei parametri utili:

  • 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)
    )
}

Un campo di testo su più righe, con due righe modificabili più l'etichetta

Consigliamo TextField rispetto a BasicTextField quando il design richiede un materiale TextField o OutlineTextField. Tuttavia, l'elemento BasicTextField deve essere utilizzato quando si realizzano progetti che non richiedono le decorazioni specificate nella specifica Materiale.

Definisci lo stile con l'API Brush

Puoi utilizzare l'API Brush per stili più avanzati in TextField. La seguente sezione descrive come utilizzare un Pennello per aggiungere un gradiente colorato all'input TextField.

Per ulteriori informazioni sull'utilizzo dell'API Brush per definire lo stile del testo, consulta Attivare gli stili avanzati con l'API Brush.

Implementa gradienti colorati utilizzando TextStyle

Per implementare un gradiente colorato durante la digitazione all'interno di un TextField, imposta il pennello che preferisci su TextStyle per TextField. In questo esempio, usiamo un pennello integrato con un linearGradient per visualizzare l'effetto sfumatura arcobaleno durante la digitazione del testo in TextField.

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

Utilizzare buildAnnotatedString e SpanStyle, insieme a linearGradient, per personalizzare solo una porzione di testo.
Figura 3. Utilizzo di buildAnnotatedString e SpanStyle, insieme a linearGradient, per personalizzare solo una porzione di testo.

Impostare le opzioni della tastiera

TextField consente di impostare le opzioni di configurazione della tastiera, come il layout della tastiera, o di attivare la correzione automatica, se supportata dalla tastiera. Alcune opzioni potrebbero non essere garantite se la tastiera software non è conforme alle opzioni qui fornite. Ecco l'elenco delle opzioni di tastiera supportate:

  • capitalization
  • autoCorrect
  • keyboardType
  • imeAction

Formato input

TextField consente di impostare un VisualTransformation nel valore di input, ad esempio sostituendo i caratteri con * per le password o inserendo trattini ogni 4 cifre per un numero di carta di credito:

@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)
    )
}

Un campo di immissione di testo della password, con il testo mascherato.

Altri esempi sono disponibili nel codice sorgente di VisualTransformationSamples.

Pulisci input

Un'attività comune durante la modifica di un testo è eliminare i caratteri iniziali o trasformare in altro modo la stringa di input ogni volta che viene modificata.

Come modello, dovresti presumere che la tastiera possa apportare modifiche arbitrarie e di grandi dimensioni ogni onValueChange. Questo può accadere, ad esempio, se l'utente utilizza la correzione automatica, sostituisce una parola con un'emoji o altre funzionalità di modifica intelligente. Per gestire correttamente questo problema, scrivi qualsiasi logica di trasformazione supponendo che il testo attuale passato a onValueChange non sia correlato ai valori precedenti o successivi che verranno passati a onValueChange.

Per implementare un campo di testo che non consenta gli zeri iniziali, puoi rimuovere tutti gli zeri iniziali a ogni modifica del valore.

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

Per controllare la posizione del cursore durante la pulizia del testo, utilizza il sovraccarico TextFieldValue di TextField come parte dello stato.

Best practice per lo stato

Di seguito è riportata una serie di best practice per definire e aggiornare lo stato TextField in modo da evitare problemi di input nella tua app.

  • Utilizza MutableState per rappresentare lo stato TextField: evita di utilizzare stream reattivi come StateFlow per rappresentare lo stato TextField, poiché queste strutture potrebbero introdurre ritardi asincroni.

class SignUpViewModel : ViewModel() {

    var username by mutableStateOf("")
        private set

    /* ... */
}

  • Evita ritardi nell'aggiornamento dello stato: quando chiami onValueChange, aggiorna i TextField in modo sincrono e immediato:

// 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) }
        /*...*/
    )
}

  • Dove definire lo stato: se lo stato TextField richiede le convalide della logica di business durante la digitazione, è corretto istruire lo stato su ViewModel. In caso contrario, puoi usare componenti componibili o una classe di un statale come fonte di riferimento. Per saperne di più su dove istruire il tuo stato, consulta la documentazione sull'allestimento dello stato.