Obsługa danych wejściowych użytkownika

TextField pozwala użytkownikom wpisywać i modyfikować tekst. Na tej stronie opisujemy, jak wdrożyć funkcję TextField, zmienić styl wprowadzania danych TextField i skonfigurować inne opcje TextField, takie jak opcje klawiatury i wizualne przekształcanie danych wejściowych użytkownika.

Wybierz implementację TextField

Istnieją 2 poziomy wdrażania TextField:

  1. TextField to implementacja Material Design. Zalecamy wybranie tej implementacji, ponieważ jest ona zgodna z wytycznymi dotyczącymi Material Design:
  2. BasicTextField umożliwia użytkownikom edytowanie tekstu za pomocą klawiatury sprzętowej lub programowej, ale nie zawiera żadnych elementów dekoracyjnych, takich jak podpowiedź czy placeholder.

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

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

pole tekstowe z możliwością edytowania zawierające słowo;

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

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

Pole tekstowe z możliwością edycji, z fioletowym obramowaniem i etykietą.

Styl TextField

TextFieldBasicTextField mają wiele wspólnych parametrów, które można dostosować. Pełna lista TextField jest dostępna w źródłowym kodzie TextField. Oto niepełna lista przydatnych parametrów:

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

Wielowierszowe pole tekstowe z 2 wierszami do edycji i etykietą

Jeśli projekt wymaga użycia atrybutu Material TextField lub OutlinedTextField, zalecamy użycie wartości TextField zamiast BasicTextField. BasicTextField należy jednak używać w przypadku projektów budynków, które nie wymagają dekoracji ze specyfikacji Material Design.

Stylizowanie danych za pomocą interfejsu Brush API

Aby uzyskać bardziej zaawansowane efekty stylizacji w TextField, możesz użyć interfejsu Brush API. W tej sekcji opisano, jak za pomocą pędzla dodać kolorowy gradient do wejścia TextField.

Więcej informacji o używaniu interfejsu Brush API do stylizacji tekstu znajdziesz w artykule Włączanie zaawansowanego stylizowania za pomocą interfejsu Brush API.

Implementowanie kolorowych gradientów za pomocą TextStyle

Aby zastosować kolorowy gradient podczas pisania w ramach TextField, ustaw wybrany przez siebie pędzel jako TextStyle dla TextField. W tym przykładzie używamy wbudowanego pędzla z linearGradient, aby wyświetlić efekt gradientu tęczy podczas wpisywania tekstu w TextField.

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

Użycie metody buildAnnotatedString i SpanStyle razem z linearGradient do dostosowania tylko części tekstu.
Rysunek 3. Używanie elementów buildAnnotatedString i SpanStyle oraz elementu linearGradient do dostosowywania tylko części tekstu.

Ustawianie opcji klawiatury

TextField pozwala ustawić opcje konfiguracji klawiatury, takie jak układ klawiatury, lub włączyć autokorektę, jeśli jest obsługiwana przez klawiaturę. Niektóre opcje mogą nie być dostępne, jeśli klawiatura programowa nie jest zgodna z podanymi tutaj opcjami. Oto lista obsługiwanych opcji klawiatury:

  • capitalization
  • autoCorrect
  • keyboardType
  • imeAction

Formatowanie danych wejściowych

TextField umożliwia ustawienie VisualTransformation wartości wejściowej, np. zastąpienie znaków za pomocą * w przypadku haseł lub wstawienie łączników co 4 cyfry w przypadku numeru karty kredytowej:

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

Pole tekstowe hasła z zamaskowanym tekstem

Więcej przykładów znajdziesz w kodzie źródłowym VisualTransformationSamples.

Czyste dane wejściowe

Podczas edycji tekstu często trzeba usuwać początkowe znaki lub w inny sposób przekształcać ciąg wejściowy za każdym razem, gdy ulegnie zmianie.

W przypadku modelu należy założyć, że klawiatura może wprowadzać dowolne i znaczne zmiany w każdym onValueChange. Może się to zdarzyć, jeśli użytkownik skorzysta z autokorekty, zastąpi słowo emotikonem lub użyje innych funkcji inteligentycznego edytowania. Aby poprawnie obsłużyć tę funkcję, napisz logikę przekształcania z założenia, że bieżący tekst przekazany do onValueChange nie ma związku z poprzednimi ani kolejnymi wartościami, które zostaną przekazane do onValueChange.

Aby wdrożyć pole tekstowe, które nie zezwala na zera na początku, możesz usunąć wszystkie zera na początku przy każdej zmianie wartości.

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

Aby kontrolować położenie kursora podczas czyszczenia tekstu, użyj przeciążenia TextFieldValue TextField jako części stanu.

Sprawdzone metody dotyczące stanu

Poniżej znajdziesz kilka sprawdzonych metod definiowania i aktualizowania stanu TextField, aby zapobiec problemom z danymi wejściowymi w aplikacji.

  • Używaj MutableState do reprezentowania stanu TextField: unikaj używania strumieni reaktywnych, takich jak StateFlow do reprezentowania stanu TextField, ponieważ mogą one powodować asynchroniczne opóźnienia.

class SignUpViewModel : ViewModel() {

    var username by mutableStateOf("")
        private set

    /* ... */
}

  • Unikaj opóźnień w aktualizowaniu stanu: gdy wywołujesz funkcję onValueChange, zaktualizuj obiekt TextField synchronicznie i natychmiast:

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

  • Gdzie zdefiniować stan: jeśli stan TextField wymaga weryfikacji logiki biznesowej podczas pisania kodu, możesz przenieść ten stan do elementu ViewModel. Jeśli tak nie jest, możesz użyć komponentów lub klasy uchwytu stanu jako źródła informacji. Więcej informacji o tym, gdzie można przenosić stan, znajdziesz w dokumentacji dotyczącej przenoszenia stanu.