Konfigurowanie pól tekstowych

TextField umożliwia użytkownikom wpisywanie i modyfikowanie tekstu. Możesz używać 2 rodzajów pól tekstowych: pól tekstowych opartych na stanie i pól tekstowych opartych na wartości. Wybierz typ, dla którego chcesz wyświetlać treści:

Zalecamy używanie pól tekstowych opartych na stanie, ponieważ zapewniają one bardziej kompletne i niezawodne podejście do zarządzania stanem elementu TextField. W tabeli poniżej przedstawiono różnice między tymi rodzajami pól tekstowych oraz główne zalety pól tekstowych opartych na stanie:

Funkcja

Pola tekstowe oparte na wartości

Pola tekstowe dotyczące stanu

Świadczenie stanowe

Zarządzanie stanem

Aktualizuje stan pola tekstowego za pomocą wywołania zwrotnego onValueChange. Odpowiadasz za aktualizowanie value w swoim stanie na podstawie zmian zgłaszanych przez onValueChange.

Jawnie używa obiektu TextFieldState do zarządzania stanem wprowadzania tekstu (wartość, zaznaczenie i kompozycja). Ten stan można zapamiętać i udostępnić.

  • Usunęliśmy wywołanie zwrotne onValueChange, co uniemożliwia wprowadzanie zachowań asynchronicznych.
  • Stan jest zachowywany po rekompozycji, zmianie konfiguracji i śmierci procesu.

Przekształcenie wizualne

Używa VisualTransformation do modyfikowania sposobu wyświetlania tekstu. Zwykle obejmuje to formatowanie danych wejściowych i wyjściowych w jednym kroku.

Używa InputTransformation do modyfikowania danych wejściowych użytkownika przed ich zapisaniem w stanie i OutputTransformation do formatowania zawartości pola tekstowego bez zmiany danych stanu.

  • Nie musisz już podawać mapowania przesunięć między oryginalnym tekstem nieprzetworzonym a przekształconym tekstem za pomocą symbolu OutputTransformation.

Limity wierszy

Akceptuje singleLine: Boolean, maxLines: Int i minLines: Int do sterowania liczbą wierszy.

Używa parametru lineLimits: TextFieldLineLimits do skonfigurowania minimalnej i maksymalnej liczby wierszy, które może zajmować pole tekstowe.

  • Usuwa niejednoznaczność podczas konfigurowania limitów wierszy, udostępniając parametr lineLimits typu TextFieldLineLimits.

Bezpieczne pole tekstowe

Nie dotyczy

SecureTextField to komponent, który jest oparty na polach tekstowych opartych na stanie i służy do tworzenia pola hasła.

  • Umożliwia optymalizację pod kątem bezpieczeństwa i ma predefiniowany interfejs z textObfuscationMode.

Na tej stronie dowiesz się, jak zaimplementować element TextField, określić styl danych wejściowych 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 wdrożenia TextField:

  1. TextField to implementacja Material Design. Zalecamy wybranie tej implementacji, ponieważ jest ona zgodna z wytycznymi Material Design:
  2. BasicTextField umożliwia użytkownikom edytowanie tekstu za pomocą klawiatury sprzętowej lub klawiatury ekranowej, ale nie zapewnia żadnych dekoracji, takich jak podpowiedź czy tekst zastępczy.

TextField(
    state = rememberTextFieldState(initialText = "Hello"),
    label = { Text("Label") }
)

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

OutlinedTextField(
    state = rememberTextFieldState(),
    label = { Text("Label") }
)

Pole tekstowe z możliwością edytowania, z fioletową ramką i etykietą.

Styl TextField

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

  • textStyle
  • lineLimits

TextField(
    state = rememberTextFieldState("Hello\nWorld\nInvisible"),
    lineLimits = TextFieldLineLimits.MultiLine(maxHeightInLines = 2),
    placeholder = { Text("") },
    textStyle = TextStyle(color = Color.Blue, fontWeight = FontWeight.Bold),
    label = { Text("Enter text") },
    modifier = Modifier.padding(20.dp)
)

Wielowierszowe pole tekstowe z 2 wierszami z możliwością edytowania i etykietą.

Jeśli projekt wymaga użycia elementu Material TextField lub OutlinedTextField, zalecamy użycie elementu TextField zamiast BasicTextField. Jednak BasicTextField należy używać podczas tworzenia projektów, które nie wymagają dekoracji z specyfikacji Material.

Stylizowanie danych wejściowych za pomocą interfejsu Brush API

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

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

Implementowanie gradientów kolorów za pomocą TextStyle

Aby zastosować kolorowy gradient podczas pisania w TextField, ustaw wybrany 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.

val brush = remember {
    Brush.linearGradient(
        colors = listOf(Color.Red, Color.Yellow, Color.Green, Color.Blue, Color.Magenta)
    )
}
TextField(
    state = rememberTextFieldState(), textStyle = TextStyle(brush = brush)
)

Tekst wpisywany w polu tekstowym z efektem gradientu w kolorach tęczy.
Rysunek 1. Efekt gradientu tęczy dla treści TextField.

Zarządzanie stanem pola tekstowego

TextField używa specjalnej klasy przechowującej stan o nazwie TextFieldState do przechowywania treści i wyboru. TextFieldState jest przeznaczony do umieszczania w dowolnym miejscu w architekturze. TextFieldState udostępnia 2 główne właściwości:

  • initialText: zawartość TextField.
  • initialSelection: wskazuje, gdzie znajduje się kursor lub zaznaczenie.

TextFieldState różni się od innych metod, takich jak wywołanie zwrotne onValueChange, tym, że TextFieldState w pełni obejmuje cały przepływ danych wejściowych. Obejmuje to używanie prawidłowych struktur danych pomocniczych, wstawianie filtrów i funkcji formatujących oraz synchronizowanie wszystkich zmian pochodzących z różnych źródeł.

Możesz używać funkcji TextFieldState() do przenoszenia stanu w TextField. W tym celu zalecamy użycie funkcji rememberTextFieldState(). rememberTextFieldState() tworzy instancję TextFieldState w kompozycji, dba o to, aby obiekt stanu był zapamiętany, i zapewnia wbudowaną funkcję zapisywania i przywracania:

val usernameState = rememberTextFieldState()
TextField(
    state = usernameState,
    lineLimits = TextFieldLineLimits.SingleLine,
    placeholder = { Text("Enter Username") }
)

rememberTextFieldState może mieć pusty parametr lub wartość początkową przekazaną w celu reprezentowania wartości tekstu podczas inicjowania. Jeśli w kolejnej rekompozycji zostanie przekazana inna wartość, stan nie zostanie zaktualizowany. Aby zaktualizować stan po jego zainicjowaniu, wywołaj metody edycji na obiekcie TextFieldState.

TextField(
    state = rememberTextFieldState(initialText = "Username"),
    lineLimits = TextFieldLineLimits.SingleLine,
)

Pole tekstowe z tekstem Nazwa użytkownika wyświetlanym wewnątrz pola.
Rysunek 2. TextField z tekstem początkowym „Nazwa użytkownika”.

Modyfikowanie tekstu za pomocą TextFieldBuffer

Element TextFieldBuffer służy jako kontener tekstu z możliwością edytowania, podobnie jak element StringBuilder. Zawiera zarówno treść tekstową, jak i informacje o wybranym fragmencie.

Często spotykasz TextFieldBuffer jako zakres odbiorcy w funkcjach takich jak TextFieldState.edit, InputTransformation.transformInput lub OutputTransformation.transformOutput. W tych funkcjach możesz w razie potrzeby odczytywać lub aktualizować TextFieldBuffer. Następnie zmiany te są zatwierdzane w TextFieldState lub przekazywane do potoku renderowania w przypadku OutputTransformation.

Możesz używać standardowych funkcji edycji, takich jak append, insert, replace lub delete, aby modyfikować zawartość bufora. Aby zmienić stan zaznaczenia, możesz bezpośrednio ustawić zmienną selection: TextRange lub użyć funkcji narzędziowych, takich jak placeCursorAtEnd lub selectAll. Sam wybór jest reprezentowany przez znak TextRange, gdzie indeks początkowy jest włączony, a indeks końcowy jest wyłączony. Znak TextRange z identycznymi wartościami początkową i końcową, np. (3, 3), oznacza pozycję kursora bez zaznaczonych znaków.

val phoneNumberState = rememberTextFieldState("1234567890")

TextField(
    state = phoneNumberState,
    keyboardOptions = KeyboardOptions(
        keyboardType = KeyboardType.Phone
    ),
    inputTransformation = InputTransformation.maxLength(10).then {
        if (!asCharSequence().isDigitsOnly()) {
            revertAllChanges()
        }
    },
    outputTransformation = OutputTransformation {
        if (length > 0) insert(0, "(")
        if (length > 4) insert(4, ")")
        if (length > 8) insert(8, "-")
    }
)

Edytuj tekst w TextFieldState

Stan można edytować bezpośrednio za pomocą zmiennej stanu na kilka sposobów:

  • edit: umożliwia edytowanie zawartości stanu i udostępnia funkcje TextFieldBuffer, dzięki czemu możesz używać metod takich jak insert, replace, append i innych.

    // Initial textFieldState text passed in is "I love Android"
    // textFieldState.text : I love Android
    // textFieldState.selection: TextRange(14, 14)
    textFieldState.edit { insert(14, "!") }
    // textFieldState.text : I love Android!
    // textFieldState.selection: TextRange(15, 15)
    textFieldState.edit { replace(7, 14, "Compose") }
    // textFieldState.text : I love Compose!
    // textFieldState.selection: TextRange(15, 15)
    textFieldState.edit { append("!!!") }
    // textFieldState.text : I love Compose!!!!
    // textFieldState.selection: TextRange(18, 18)
    textFieldState.edit { selectAll() }
    // textFieldState.text : I love Compose!!!!
    // textFieldState.selection: TextRange(0, 18)

  • setTextAndPlaceCursorAtEnd: czyści bieżący tekst, zastępuje go podanym tekstem i ustawia kursor na końcu.

    textFieldState.setTextAndPlaceCursorAtEnd("I really love Android")
    // textFieldState.text : I really love Android
    // textFieldState.selection : TextRange(21, 21)

  • clearText: usuwa cały tekst.

    textFieldState.clearText()
    // textFieldState.text :
    // textFieldState.selection : TextRange(0, 0)

Więcej informacji o innych funkcjach TextFieldState znajdziesz w TextFieldState.

Modyfikowanie danych wejściowych użytkownika

W sekcjach poniżej opisujemy, jak modyfikować dane wejściowe użytkownika. Przekształcanie danych wejściowych umożliwia filtrowanie TextField danych wejściowych podczas pisania przez użytkownika, a przekształcanie danych wyjściowych formatuje dane wejściowe użytkownika przed wyświetleniem ich na ekranie.

Filtrowanie danych wejściowych użytkownika za pomocą przekształceń danych wejściowych

Przekształcenie danych wejściowych umożliwia filtrowanie danych wejściowych od użytkownika. Jeśli np. TextField przyjmuje amerykański numer telefonu, chcesz akceptować tylko 10 cyfr. Wyniki InputTransformation są zapisywane w TextFieldState.

Dostępne są wbudowane filtry do typowych InputTransformationprzypadków użycia. Aby ograniczyć długość, zadzwoń pod numer InputTransformation.maxLength():

TextField(
    state = rememberTextFieldState(),
    lineLimits = TextFieldLineLimits.SingleLine,
    inputTransformation = InputTransformation.maxLength(10)
)

Niestandardowe przekształcenia danych wejściowych

InputTransformation to interfejs z jedną funkcją. Podczas wdrażania niestandardowego InputTransformation musisz zastąpić TextFieldBuffer.transformInput:

class CustomInputTransformation : InputTransformation {
    override fun TextFieldBuffer.transformInput() {
    }
}

W przypadku numeru telefonu dodaj niestandardową transformację danych wejściowych, która zezwala na wpisywanie w polu TextField tylko cyfr:

class DigitOnlyInputTransformation : InputTransformation {
    override fun TextFieldBuffer.transformInput() {
        if (!asCharSequence().isDigitsOnly()) {
            revertAllChanges()
        }
    }
}

Łączenie przekształceń danych wejściowych

Aby dodać do wpisywanego tekstu kilka filtrów, połącz jeInputTransformation za pomocą funkcji rozszerzenia then. Filtry są wykonywane po kolei. Zalecamy stosowanie najpierw najbardziej selektywnych filtrów, aby uniknąć niepotrzebnych przekształceń danych, które ostatecznie zostaną odfiltrowane.

TextField(
    state = rememberTextFieldState(),
    inputTransformation = InputTransformation.maxLength(6)
        .then(CustomInputTransformation()),
)

Po dodaniu przekształceń danych wejściowych pole TextField może zawierać maksymalnie 10 cyfr.

Formatowanie danych wejściowych przed wyświetleniem

OutputTransformationumożliwiają formatowanie danych wprowadzanych przez użytkownika przed ich wyświetleniem na ekranie. W przeciwieństwie do InputTransformation formatowanie wykonane za pomocą OutputTransformation nie jest zapisywane w TextFieldState. W oparciu o poprzedni przykład numeru telefonu musisz dodać nawiasy i myślniki w odpowiednich miejscach:

Amerykański numer telefonu, prawidłowo sformatowany z nawiasami, łącznikami i odpowiednimi indeksami.
Rysunek 3. amerykański numer telefonu z prawidłowym formatowaniem i odpowiednimi indeksami;

Jest to zaktualizowany sposób obsługi VisualTransformation w TextField opartych na wartościach. Kluczową różnicą jest to, że nie musisz obliczać mapowań przesunięć.

OutputTransformation to interfejs z jedną metodą abstrakcyjną. Aby wdrożyć niestandardową funkcję OutputTransformation, musisz zastąpić metodę transformOutput:

class CustomOutputTransformation : OutputTransformation {
    override fun TextFieldBuffer.transformOutput() {
    }
}

Aby sformatować numer telefonu, dodaj nawias otwierający na pozycji 0, nawias zamykający na pozycji 4 i myślnik na pozycji 8 do OutputTransformation:

class PhoneNumberOutputTransformation : OutputTransformation {
    override fun TextFieldBuffer.transformOutput() {
        if (length > 0) insert(0, "(")
        if (length > 4) insert(4, ")")
        if (length > 8) insert(8, "-")
    }
}

Następnie dodaj OutputTransformation do TextField:

TextField(
    state = rememberTextFieldState(),
    outputTransformation = PhoneNumberOutputTransformation()
)

Jak działają przekształcenia

Na diagramie poniżej widać przepływ od wprowadzania tekstu do przekształcenia i wygenerowania danych wyjściowych:

Wizualizacja pokazująca, jak dane wejściowe w postaci tekstu są przekształcane, zanim staną się danymi wyjściowymi w postaci tekstu.
Rysunek 4. Diagram pokazujący, jak wprowadzony tekst przechodzi transformacje, zanim stanie się tekstem wyjściowym.
  1. Dane wejściowe są odbierane ze źródła sygnału.
  2. Dane wejściowe są filtrowane przez InputTransformation, który jest zapisywany w obiekcie TextFieldState.
  3. Dane wejściowe są przekazywane przez OutputTransformation w celu sformatowania.
  4. Dane wejściowe są prezentowane w TextField.

Ustawianie opcji klawiatury

TextField umożliwia ustawienie opcji konfiguracji klawiatury, takich jak układ klawiatury, lub włączenie autokorekty, jeśli jest obsługiwana przez klawiaturę. Niektóre opcje mogą nie być gwarantowane, jeśli klawiatura ekranowa nie jest zgodna z opcjami podanymi tutaj. Oto lista obsługiwanych opcji klawiatury:

  • capitalization
  • autoCorrect
  • keyboardType
  • imeAction

Dodatkowe materiały