Obsługa danych wejściowych użytkownika

TextField umożliwia użytkownikom wpisywanie i modyfikowanie tekstu. Na tej stronie opisujemy, jak implementować reguły TextField i określać styl wprowadzania tekstu TextField oraz konfigurować inne opcje TextField, np. opcje klawiatury i zmieniające wygląd danych wejściowych użytkownika.

Wybierz implementację TextField

Są 2 poziomy implementacji TextField:

  1. TextField to implementacja Material Design. Zalecamy zastosowanie tej implementacji w sposób zgodny ze wskazówkami dotyczącymi Material Design:
  2. BasicTextField umożliwia użytkownikom edytowanie tekstu za pomocą klawiatury sprzętowej lub programowej, ale nie udostępnia żadnych elementów dekoracyjnych, takich jak podpowiedź czy symbole zastępcze.

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

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

Edytowalne pole tekstowe zawierające słowo

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

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

Edytowalne pole tekstowe z fioletową ramką i etykietą.

Styl TextField

Parametry TextField i BasicTextField mają wiele wspólnych parametrów na potrzeby ich dostosowywania. Pełna lista funkcji TextField jest dostępna w kodzie źródłowym TextField. Oto lista niektórych 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 w projekcie używasz materiału TextField lub OutlineTextField, zalecamy użycie TextField zamiast BasicTextField. Atrybutu BasicTextField należy jednak używać w przypadku projektów, które nie wymagają dekoracji ze specyfikacji Material Design.

Wprowadzanie stylu za pomocą interfejsu Brush API

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

Więcej informacji o używaniu interfejsu Brush API do zmiany stylu tekstu znajdziesz w artykule o włączaniu zaawansowanego stylu za pomocą interfejsu Brush API.

Zastosuj kolorowe gradienty za pomocą pola TextStyle

Aby zaimplementować kolorowy gradient podczas pisania w TextField, ustaw wybrany pędzel jako TextStyle w: TextField. W tym przykładzie używamy wbudowanego pędzla z atrybutem linearGradient, aby wyświetlać efekt tęczy gradientu podczas wpisywania tekstu w polu 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 buildAnnotatedString i SpanStyle razem z elementami linearGradient, aby dostosować tylko fragment tekstu.
Rysunek 3. Korzystając z buildAnnotatedString i SpanStyle oraz linearGradient, możesz dostosować tylko fragment tekstu.

Ustaw opcje klawiatury

W TextField możesz ustawić opcje konfiguracji klawiatury, takie jak jej układ, lub włączyć autokorektę, jeśli jest obsługiwana przez klawiaturę. Niektóre opcje mogą nie być gwarantowane, jeśli klawiatura programowa nie jest zgodna z tymi opcjami. Oto lista obsługiwanych opcji klawiatury:

  • capitalization
  • autoCorrect
  • keyboardType
  • imeAction

Formatuj dane wejściowe

TextField pozwala ustawić VisualTransformation dla wartości wejściowej, np. zastępować znaki * w przypadku haseł lub wstawianie łą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 do wpisywania tekstu hasła z zamasowanym tekstem

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

Wyczyść dane wejściowe

Częstym zadaniem podczas edytowania tekstu jest usuwanie znaków początkowych lub przekształcanie ciągu wejściowego w inny sposób po każdej jego zmianie.

Jako model należy zakładać, że klawiatura może wprowadzać dowolne i duże zmiany każdego elementu onValueChange. Może się tak zdarzyć, jeśli na przykład użytkownik użyje autokorekty, zastąpi słowo emotikonem lub użyje innych funkcji inteligentnej edycji. Aby prawidłowo się tym zająć, napisz dowolną logikę przekształcenia przy założeniu, że bieżący tekst przekazywany do funkcji onValueChange nie jest niezwiązany z poprzednią lub następną wartością, która będzie przekazywana do funkcji onValueChange.

Aby zaimplementować pole tekstowe, które nie zezwala na zera na początku, można to zrobić, usuwając przy każdej zmianie wartości wszystkie zera wiodące.

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

Aby zmienić położenie kursora podczas czyszczenia tekstu, użyj w ramach stanu przeciążenia TextFieldTextFieldValue.

Sprawdzone metody dotyczące stanu

Poniżej znajdziesz sprawdzone metody definiowania i aktualizowania stanu TextField, aby zapobiegać problemom z danymi wejściowymi w aplikacji.

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

class SignUpViewModel : ViewModel() {

    var username by mutableStateOf("")
        private set

    /* ... */
}

  • Unikaj opóźnień w aktualizacji stanu: gdy wywołujesz onValueChange, zaktualizuj 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, możesz przenieść ten stan do ViewModel. Jeśli tak nie jest, jako źródła informacji możesz użyć funkcji kompozycyjnych lub klasy posiadacza stanu. Więcej informacji o tym, gdzie przenieść stan, znajdziesz w dokumentacji dotyczącej przewozu stanów.