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 treści, które chcesz wyświetlać:
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 znajdziesz 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 zależne od stanu |
Świadczenie stanowe |
|---|---|---|---|
Zarządzanie stanem |
Aktualizuje stan pola tekstowego za pomocą wywołania zwrotnego |
Jawnie używa obiektu |
|
Przekształcenie wizualne |
Używa |
Używa funkcji |
|
Limity wierszy |
Akceptuje wartości |
Używa |
|
Bezpieczne pole tekstowe |
Nie dotyczy |
|
|
Na tej stronie dowiesz się, jak zaimplementować TextField, określić styl TextField danych wejściowych i skonfigurować inne TextField opcje, takie jak opcje klawiatury i wizualne przekształcanie danych wejściowych użytkownika.
Wybierz implementację TextField
Istnieją 2 poziomy wdrożenia TextField:
TextFieldto implementacja Material Design. Zalecamy wybranie tej implementacji, ponieważ jest ona zgodna z wytycznymi Material Design:- Domyślny styl to wypełniony.
OutlinedTextFieldto wersja stylu z konturem
BasicTextFieldumożliwia użytkownikom edytowanie tekstu za pomocą klawiatury sprzętowej lub programowej, ale nie zawiera żadnych dekoracji, takich jak podpowiedź czy symbol zastępczy.
TextField( state = rememberTextFieldState(initialText = "Hello"), label = { Text("Label") } )
OutlinedTextField( state = rememberTextFieldState(), label = { Text("Label") } )
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:
textStylelineLimits
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) )
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.
Konfigurowanie limitów wierszy
Komponenty kompozycyjne TextField obsługują przewijanie wzdłuż jednej osi. Sposób przewijania zależy od parametru lineLimits. TextFields skonfigurowane do przewijania w jednym wierszu przewijają się w poziomie, a TextFields wielowierszowe przewijają się w pionie.
Użyj TextFieldLineLimits, aby wybrać odpowiednią konfigurację linii dla Twojego TextField:
TextField( state = rememberTextFieldState(), lineLimits = TextFieldLineLimits.SingleLine )
Konfiguracja SingleLine ma te cechy:
- Tekst nigdy nie jest zawijany i nie można w nim wstawiać nowych wierszy.
TextFieldma zawsze stałą wysokość.- Jeśli tekst się nie mieści, jest przewijany w poziomie.
TextField( state = rememberTextFieldState("Hello\nWorld\nHello\nWorld"), lineLimits = TextFieldLineLimits.MultiLine(1, 4) )
Konfiguracja MultiLine ma te cechy:
- Przyjmuje 2 parametry:
minHeightInLinesimaxHeightInLines. - Pole tekstowe ma co najmniej
minHeightInLineswysokości. - Jeśli tekst się nie mieści, zostanie zawinięty.
- Jeśli tekst wymaga więcej wierszy, pole powiększa się do wysokości
maxHeightInLinesi jest przewijane w pionie.
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 opisano, 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.
Wdrażanie gradientów kolorów za pomocą TextStyle
Aby podczas pisania w TextField zastosować gradient kolorów, 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) )
TextField.Zarządzanie stanem pola tekstowego
TextField używa specjalnej klasy przechowującej stan o nazwie TextFieldState do przechowywania treści i wyboru. TextFieldState można umieścić w dowolnym miejscu w architekturze. TextFieldState udostępnia 2 główne właściwości:
initialText: zawartośćTextField.initialSelection: wskazuje miejsce, w którym 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 formaterów oraz synchronizowanie wszystkich zmian pochodzących z różnych źródeł.
Za pomocą TextFieldState() możesz przenosić stan 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 wbudowane funkcje 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 kompozycji zostanie przekazana inna wartość, stan nie zostanie zaktualizowany.
Aby zaktualizować stan po jego zainicjowaniu, wywołaj metody edycji w TextFieldState.
TextField( state = rememberTextFieldState(initialText = "Username"), lineLimits = TextFieldLineLimits.SingleLine, )
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 zaznaczeniu.
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 przypadku 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 traktowany włącznie, a indeks końcowy – wyłącznie.
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, "-") } )
Edytowanie tekstu 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 funkcjeTextFieldBuffer, dzięki czemu możesz używać metod takich jakinsert,replace,appendi 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 TextFieldStatemateriałach referencyjnych.
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
Transformacja 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 InputTransformation zastosowań. Aby ograniczyć długość, zadzwoń pod numer InputTransformation.maxLength():
TextField( state = rememberTextFieldState(), lineLimits = TextFieldLineLimits.SingleLine, inputTransformation = InputTransformation.maxLength(10) )
Przekształcenia danych niestandardowych
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 transformacji danych wejściowych
Aby dodać do danych wejściowych kilka filtrów, połącz je za pomocą operatora InputTransformation, używając funkcji rozszerzenia then. Filtry są wykonywane kolejno. Zgodnie ze sprawdzoną metodą najpierw zastosuj najbardziej selektywne filtry, 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. Korzystając z przykładu numeru telefonu z poprzedniego kroku, musisz dodać nawiasy i myślniki w odpowiednich miejscach:
Jest to zaktualizowany sposób obsługi VisualTransformation w przypadku 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
Poniższy diagram przedstawia przepływ od wprowadzania tekstu przez przekształcanie do danych wyjściowych:
- Dane wejściowe są odbierane ze źródła sygnału.
- Dane wejściowe są filtrowane za pomocą
InputTransformation, który jest zapisywany w TextFieldState. - Dane wejściowe są przekazywane przez
OutputTransformationw celu formatowania. - 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 programowa nie jest zgodna z opcjami podanymi tutaj. Oto lista obsługiwanych opcji klawiatury:
capitalizationautoCorrectkeyboardTypeimeAction
Klasa KeyboardOptions zawiera teraz nowy parametr logiczny showKeyboardOnFocus, który jest używany specjalnie w przypadku komponentów TextField zintegrowanych z TextFieldState. Ta opcja określa zachowanie klawiatury ekranowej, gdy TextField uzyskuje fokus w inny sposób niż przez bezpośrednią interakcję użytkownika (np. programowo).
Gdy wartość KeyboardOptions.showKeyboardOnFocus jest ustawiona na „true”, klawiatura programowa nie pojawia się automatycznie, jeśli element TextField zyskuje fokus pośrednio. W takich przypadkach użytkownik musi kliknąć samą ikonę TextField, aby wyświetlić klawiaturę.
Określanie logiki interakcji z klawiaturą
Przycisk działania na klawiaturze ekranowej Androida umożliwia interaktywne odpowiedzi w aplikacji. Więcej informacji o konfigurowaniu przycisku działania znajdziesz w sekcji Ustawianie opcji klawiatury.
Aby określić, co się stanie, gdy użytkownik kliknie ten przycisk działania, użyj parametru onKeyboardAction. Ten parametr przyjmuje opcjonalny interfejs funkcyjny o nazwie KeyboardActionHandler. Interfejs KeyboardActionHandler zawiera 1 metodę: onKeyboardAction(performDefaultAction: () -> Unit).
Dostarczając implementację tej metody onKeyboardAction, możesz wprowadzić niestandardową logikę, która będzie wykonywana, gdy użytkownik naciśnie przycisk działania na klawiaturze.
Kilka standardowych typów działań klawiatury ma wbudowane domyślne zachowania.
Na przykład wybranie ImeAction.Next lub ImeAction.Previous jako typu działania spowoduje domyślne przeniesienie zaznaczenia odpowiednio do następnego lub poprzedniego pola wpisywania. Podobnie przycisk działania ustawiony na ImeAction.Done zwykle zamyka klawiaturę programową. Te domyślne funkcje są wykonywane automatycznie i nie wymagają podania KeyboardActionHandler.
Oprócz tych domyślnych działań możesz też wdrożyć działania niestandardowe.
Gdy podasz KeyboardActionHandler, jego metoda onKeyboardAction otrzyma funkcję performDefaultAction. Możesz wywołać tę funkcję performDefaultAction()w dowolnym momencie w logice niestandardowej, aby wywołać standardowe domyślne działanie powiązane z bieżącą czynnością IME.
TextField( state = textFieldViewModel.usernameState, keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next), onKeyboardAction = { performDefaultAction -> textFieldViewModel.validateUsername() performDefaultAction() } )
Ten fragment kodu ilustruje typowy przypadek użycia na ekranie rejestracji z polem nazwy użytkownika. W tym polu wybrano ImeAction.Next jako przycisk działania klawiatury. Ten wybór umożliwia szybkie i płynne przejście do kolejnego pola hasła.
Oprócz standardowej nawigacji wymagane jest zainicjowanie procesu weryfikacji w tle nazwy użytkownika, gdy użytkownik przechodzi do wpisywania hasła. Aby mieć pewność, że domyślne zachowanie przełączania fokusu właściwe dla ImeAction.Next zostanie zachowane wraz z tą niestandardową logiką weryfikacji, wywoływana jest funkcja performDefaultAction(). Wywołanie performDefaultAction()
niejawnie uruchamia system zarządzania fokusem, który przenosi fokus na
następny odpowiedni element interfejsu, zachowując oczekiwany przepływ nawigacji.
Tworzenie bezpiecznego pola hasła
SecureTextField to komponent oparty na polach tekstowych opartych na stanie, który służy do tworzenia pola hasła. Do tworzenia pól tekstowych haseł zalecamy używanie elementu SecureTextField, ponieważ domyślnie ukrywa on wpisywane znaki i wyłącza działania wycinania i kopiowania.
SecureTextField ma textObfuscationMode, który kontroluje sposób wyświetlania wpisywanych znaków. textObfuscationMode ma te opcje:
Hidden: ukrywa wszystkie dane wejściowe. Domyślne działanie na platformach desktopowych.
Visible: wyświetla wszystkie dane wejściowe.
RevealLastTyped: ukrywa wszystkie dane wejściowe z wyjątkiem ostatniego znaku. Domyślne działanie na urządzeniach mobilnych.
Dodatkowe materiały
- Automatyczne formatowanie numeru telefonu w polu tekstowym
- Wyświetlanie lub ukrywanie hasła na podstawie przełącznika użytkownika
- Sprawdzanie poprawności wpisywanych danych