Gestisci l'input utente

TextField consente agli utenti di inserire e modificare il testo. Questa pagina descrive come implementare TextField, impostare lo stile dell'input TextField e configurare altre opzioni TextField, ad esempio le opzioni della tastiera e la trasformazione visiva dell'input utente.

Scegli l'implementazione di TextField

Esistono due livelli di implementazione di TextField:

  1. TextField è l'implementazione di Material Design. Ti consigliamo di scegliere questa implementazione perché segue le linee guida di Material Design:
    • Lo stile predefinito è riempito
    • OutlinedTextField è la versione outline styling
  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 bordo e etichetta viola.

Stile TextField

TextField e BasicTextField condividono molti parametri comuni per personalizzarli. L'elenco completo per TextField è disponibile nel codice fonte 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 multilinea, con due righe modificabili più l'etichetta

Ti consigliamo di utilizzare TextField anziché BasicTextField quando il design richiede un materiale TextField o OutlinedTextField. Tuttavia, BasicTextField deve essere utilizzato quando crei design che non richiedono le decorazioni delle specifiche di Material.

Inserire lo stile con l'API Brush

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

Per ulteriori informazioni sull'utilizzo dell'API Brush per applicare stili al testo, consulta Abilitare gli stili avanzati con l'API Brush.

Implementa i gradienti colorati utilizzando TextStyle

Per implementare un gradiente colorato durante la digitazione all'interno di un TextField, imposta il pennello scelto come TextStyle per il TextField. In questo esempio, utilizziamo un pennello integrato con linearGradient per visualizzare l'effetto gradiente arcobaleno mentre il testo viene digitato nel TextField.

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

Utilizza buildAnnotatedString e SpanStyle, insieme a linearGradient, per personalizzare solo un pezzo di testo.
Figura 3. Utilizzare buildAnnotatedString e SpanStyle, insieme a linearGradient, per personalizzare solo un pezzo di testo.

Impostare le opzioni della tastiera

TextField ti consente di impostare le opzioni di configurazione della tastiera, ad esempio 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 fornite qui. Ecco l'elenco delle opzioni della tastiera supportate:

  • capitalization
  • autoCorrect
  • keyboardType
  • imeAction

Formattare l'input

TextField ti consente di impostare un VisualTransformation sul valore di input, ad esempio sostituendo i caratteri con * per le password o inserendo trattini ogni 4 cifre per il numero di una 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.

Input pulito

Un'operazione comune durante la modifica del testo è rimuovere i caratteri iniziali o trasformare la stringa di input ogni volta che cambia.

Come modello, devi assumere che la tastiera possa apportare modifiche arbitrarie e di grandi dimensioni a ogni onValueChange. Ciò 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 partendo dal presupposto che il testo attuale passato a onValueChange non è correlato ai valori precedenti o successivi che verranno passati a onValueChange.

Per implementare un campo di testo che non consenta gli zeri iniziali, puoi eliminare 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 l'overload 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 per evitare problemi di immissione nell'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 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 convalide della logica aziendale durante la digitazione, è corretto impostarlo su ViewModel. In caso contrario, puoi utilizzare composable o una classe di contenitore dello stato come fonte attendibile. Per scoprire di più su dove istruire lo stato, consulta la documentazione relativa al sollevamento dello stato.