TextField позволяет пользователям вводить и изменять текст. Существует два типа текстовых полей: на основе состояния и на основе значения. Выберите тип контента, который хотите посмотреть:
Мы рекомендуем использовать текстовые поля, основанные на состоянии, поскольку они обеспечивают более полный и надежный подход к управлению состоянием TextField. В таблице ниже описаны различия между этими типами текстовых полей и перечислены основные преимущества текстовых полей на основе состояния.
Функция |
Текстовые поля на основе ценности |
Текстовые поля на основе штата |
Государственные льготы |
|---|---|---|---|
Управление состоянием |
Обновляет состояние текстового поля с помощью обратного вызова |
Явно использует объект |
|
Визуальное преобразование |
Использует |
Использует |
|
Ограничения на количество строк |
Принимает |
Использует |
|
Защищенное текстовое поле |
Н/Д |
|
|
На этой странице описано, как реализовать TextField, настроить стиль ввода TextField и другие параметры TextField, например параметры клавиатуры и визуальное преобразование пользовательского ввода.
Выберите реализацию TextField
Существует два уровня реализации TextField:
TextField– это реализация Material Design. Мы рекомендуем выбрать этот вариант, поскольку он соответствует рекомендациям Material Design.- Стиль по умолчанию – filled.
OutlinedTextField– это версия стиля с контуром.
BasicTextFieldпозволяет пользователям редактировать текст с помощью аппаратной или виртуальной клавиатуры, но не предоставляет никаких декоративных элементов, таких как подсказка или плейсхолдер.
TextField( state = rememberTextFieldState(initialText = "Hello"), label = { Text("Label") } )
OutlinedTextField( state = rememberTextFieldState(), label = { Text("Label") } )
Стиль TextField
У TextField и BasicTextField много общих параметров для настройки.
Полный список для TextField доступен в исходном коде TextField. Ниже приведен неполный список полезных параметров.
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) )
Мы рекомендуем использовать TextField вместо BasicTextField, если в вашем дизайне используется Material TextField или OutlinedTextField. Однако BasicTextField следует использовать при создании дизайнов, которым не нужны декорации из спецификации Material.
Настройте ограничения для строк
TextField composables support scrolling along a single axis. Поведение прокрутки определяется параметром lineLimits. TextField, настроенные для одной строки, прокручиваются по горизонтали, а многострочные TextField – по вертикали.
Используйте TextFieldLineLimits, чтобы выбрать подходящую конфигурацию для TextField:
TextField( state = rememberTextFieldState(), lineLimits = TextFieldLineLimits.SingleLine )
Конфигурация SingleLine имеет следующие характеристики:
- Текст не переносится и не позволяет добавлять новые строки.
TextFieldвсегда имеет фиксированную высоту.- Если текст не помещается, он прокручивается по горизонтали.
TextField( state = rememberTextFieldState("Hello\nWorld\nHello\nWorld"), lineLimits = TextFieldLineLimits.MultiLine(1, 4) )
Конфигурация MultiLine имеет следующие характеристики:
- Принимает два параметра:
minHeightInLinesиmaxHeightInLines. - Высота текстового поля составляет не менее
minHeightInLines. - Если текст не помещается, он будет перенесен.
- Если текст не помещается, поле увеличивается до
maxHeightInLinesи появляется вертикальная прокрутка.
Стилизация ввода с помощью Brush API
Для более сложного оформления TextField можно использовать Brush API.
В следующем разделе описывается, как использовать Brush, чтобы добавить цветной градиент к входным данным TextField.
Подробнее о том, как использовать Brush API для оформления текста…
Как реализовать цветные градиенты с помощью TextStyle
Чтобы при вводе текста в TextField использовался градиент цвета, задайте нужную кисть в качестве TextStyle для TextField. В этом примере мы используем встроенную кисть с linearGradient, чтобы увидеть эффект радужного градиента при вводе текста в 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.Управление состоянием текстового поля
TextField использует специальный класс хранилища состояния TextFieldState для контента и выбора. TextFieldState можно разместить в любом месте вашей архитектуры. TextFieldState предоставляет два основных свойства:
initialText– содержимоеTextField.initialSelection: указывает, где находится курсор или выделенный фрагмент.
Отличие TextFieldState от других подходов, например обратного вызова onValueChange, заключается в том, что TextFieldState полностью инкапсулирует весь поток ввода. Это включает использование правильных структур данных, встроенных фильтров и средств форматирования, а также синхронизацию всех правок, поступающих из разных источников.
Вы можете использовать TextFieldState(), чтобы поднять состояние в TextField. Для этого мы рекомендуем использовать функцию rememberTextFieldState().
rememberTextFieldState() создает экземпляр TextFieldState в composable-функции, обеспечивает запоминание объекта состояния и предоставляет встроенные функции сохранения и восстановления:
val usernameState = rememberTextFieldState() TextField( state = usernameState, lineLimits = TextFieldLineLimits.SingleLine, placeholder = { Text("Enter Username") } )
rememberTextFieldState может иметь пустой параметр или начальное значение, переданное для представления значения текста при инициализации. Если при последующей рекомпозиции передается другое значение, значение состояния не обновляется.
Чтобы обновить статус после инициализации, вызовите методы редактирования в TextFieldState.
TextField( state = rememberTextFieldState(initialText = "Username"), lineLimits = TextFieldLineLimits.SingleLine, )
TextField с текстом "Имя пользователя".Изменить текст с помощью TextFieldBuffer
TextFieldBuffer – это редактируемый текстовый контейнер, похожий по функциям на StringBuilder. Он содержит как текстовый контент, так и информацию о выделении.
Вы часто будете сталкиваться с TextFieldBuffer в качестве области получателя в таких функциях, как TextFieldState.edit, InputTransformation.transformInput или OutputTransformation.transformOutput. В этих функциях вы можете читать или обновлять TextFieldBuffer по мере необходимости. После этого изменения либо фиксируются в TextFieldState, либо передаются в конвейер рендеринга в случае OutputTransformation.
Для изменения содержимого буфера можно использовать стандартные функции редактирования, такие как append, insert, replace или delete. Чтобы изменить состояние выбора, задайте переменную selection: TextRange напрямую или используйте служебные функции, например placeCursorAtEnd или selectAll. Сам выбор представлен в виде TextRange, где начальный индекс включен, а конечный – исключен.
Объект TextRange с одинаковыми значениями начала и конца, например (3, 3), обозначает позицию курсора без выделенных символов.
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, "-") } )
Изменить текст в TextFieldState
Существует несколько методов, которые позволяют редактировать состояние непосредственно через переменную состояния:
edit– позволяет редактировать содержимое состояния и предоставляет функцииTextFieldBuffer, чтобы вы могли использовать такие методы, какinsert,replace,appendи т. д.// 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– удаляет текущий текст, заменяет его на указанный и устанавливает курсор в конце.textFieldState.setTextAndPlaceCursorAtEnd("I really love Android") // textFieldState.text : I really love Android // textFieldState.selection : TextRange(21, 21)
clearText: удаляет весь текст.textFieldState.clearText() // textFieldState.text : // textFieldState.selection : TextRange(0, 0)
Информацию о других функциях TextFieldState можно найти в справочнике по TextFieldState.
Изменение пользовательского ввода
В следующих разделах описано, как изменить пользовательский ввод.
Преобразование ввода позволяет фильтровать ввод TextField, пока пользователь печатает, а преобразование вывода форматирует пользовательский ввод перед его отображением на экране.
Как фильтровать пользовательский ввод с помощью преобразования входных данных
Преобразование ввода позволяет фильтровать входные данные от пользователя. Например, если TextField принимает американский номер телефона, то в нем должно быть только 10 цифр. Результаты InputTransformation сохраняются в TextFieldState.
Для распространенных сценариев использования InputTransformation есть встроенные фильтры. Чтобы ограничить длину, вызовите InputTransformation.maxLength():
TextField( state = rememberTextFieldState(), lineLimits = TextFieldLineLimits.SingleLine, inputTransformation = InputTransformation.maxLength(10) )
Специальные преобразования входных данных
InputTransformation – это интерфейс с одной функцией. При реализации собственного класса InputTransformation необходимо переопределить метод TextFieldBuffer.transformInput:
class CustomInputTransformation : InputTransformation { override fun TextFieldBuffer.transformInput() { } }
Для номера телефона добавьте специальное преобразование ввода, которое разрешает вводить в TextField только цифры.
class DigitOnlyInputTransformation : InputTransformation { override fun TextFieldBuffer.transformInput() { if (!asCharSequence().isDigitsOnly()) { revertAllChanges() } } }
Преобразования входных данных в цепочке
Чтобы добавить несколько фильтров для текстового ввода, объедините InputTransformation с помощью функции расширения then. Фильтры применяются последовательно. Рекомендуем сначала применять фильтры с наиболее строгими критериями, чтобы не тратить время на преобразование данных, которые в итоге будут отфильтрованы.
TextField( state = rememberTextFieldState(), inputTransformation = InputTransformation.maxLength(6) .then(CustomInputTransformation()), )
После добавления преобразований ввода поле TextField принимает не более 10 цифр.
Форматирование входных данных перед их отображением
OutputTransformation позволяют форматировать пользовательский ввод перед его отображением на экране. В отличие от InputTransformation, форматирование, выполненное с помощью OutputTransformation, не сохраняется в TextFieldState. Продолжая пример с номером телефона, вам нужно добавить скобки и дефисы в нужных местах:
Это обновленный способ обработки VisualTransformation в TextField на основе ценности. Ключевое отличие заключается в том, что вам не нужно рассчитывать сопоставления смещений.
OutputTransformation – это интерфейс с одним абстрактным методом. Чтобы реализовать собственный класс OutputTransformation, необходимо переопределить метод transformOutput:
class CustomOutputTransformation : OutputTransformation { override fun TextFieldBuffer.transformOutput() { } }
Чтобы отформатировать номер телефона, добавьте открывающую скобку в индекс 0, закрывающую скобку в индекс 4 и дефис в индекс 8 в OutputTransformation:
class PhoneNumberOutputTransformation : OutputTransformation { override fun TextFieldBuffer.transformOutput() { if (length > 0) insert(0, "(") if (length > 4) insert(4, ")") if (length > 8) insert(8, "-") } }
Затем добавьте OutputTransformation в TextField:
TextField( state = rememberTextFieldState(), outputTransformation = PhoneNumberOutputTransformation() )
Как работают преобразования
На следующей диаграмме показан поток от ввода текста к преобразованию и выводу:
- Сигнал поступает из источника.
- Входные данные фильтруются через
InputTransformation, который сохраняется в TextFieldState. - Входные данные передаются через
OutputTransformationдля форматирования. - Входные данные представлены в
TextField.
Как настроить параметры клавиатуры
TextField позволяет задать параметры клавиатуры, например раскладку, или включить автозамену, если она поддерживается. Некоторые параметры могут не поддерживаться, если виртуальная клавиатура не соответствует указанным здесь параметрам. Ниже приведен список поддерживаемых клавиатур.
capitalizationautoCorrectkeyboardTypeimeAction
В класс KeyboardOptions добавлен новый логический параметр showKeyboardOnFocus, который используется специально для компонентов TextField, интегрированных с TextFieldState. Этот параметр определяет поведение виртуальной клавиатуры, когда фокус переходит на TextField не в результате прямого взаимодействия с пользователем (например, программно).
Если для KeyboardOptions.showKeyboardOnFocus задано значение true, виртуальная клавиатура не появляется автоматически, когда фокус переходит на TextField косвенно. В таких случаях пользователю нужно нажать на TextField, чтобы открыть клавиатуру.
Определите логику взаимодействия с клавиатурой
Командная кнопка на виртуальной клавиатуре Android позволяет пользователям взаимодействовать с приложением. Подробнее о том, как настроить командную кнопку…
Чтобы определить, что происходит, когда пользователь нажимает на эту командную кнопку, используйте параметр onKeyboardAction. Этот параметр принимает необязательный функциональный интерфейс с именем KeyboardActionHandler. Интерфейс KeyboardActionHandler содержит один метод – onKeyboardAction(performDefaultAction: () -> Unit).
Реализовав этот метод onKeyboardAction, вы можете добавить собственную логику, которая будет выполняться, когда пользователь нажимает командную кнопку на клавиатуре.
Для нескольких стандартных типов действий клавиатуры предусмотрены встроенные режимы работы по умолчанию.
Например, если выбрать тип действия ImeAction.Next или ImeAction.Previous, фокус по умолчанию будет перемещаться на следующее или предыдущее поле ввода соответственно. Аналогично, командная кнопка, для которой задано значение ImeAction.Done, обычно закрывает виртуальную клавиатуру. Эти функции по умолчанию выполняются автоматически и не требуют указания KeyboardActionHandler.
Помимо действий по умолчанию, вы можете настроить собственные.
Когда вы предоставляете KeyboardActionHandler, его метод onKeyboardAction получает функцию performDefaultAction. Вы можете вызвать эту функцию performDefaultAction() в любой точке вашей пользовательской логики, чтобы также запустить стандартное поведение по умолчанию, связанное с текущим действием IME.
TextField( state = textFieldViewModel.usernameState, keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next), onKeyboardAction = { performDefaultAction -> textFieldViewModel.validateUsername() performDefaultAction() } )
Этот фрагмент иллюстрирует распространенный вариант использования на экране регистрации с полем имени пользователя. Для этого поля в качестве командной кнопки на клавиатуре выбрано значение "ImeAction.Next". Это позволяет быстро и легко перейти к следующему полю пароля.
Помимо стандартной навигации, необходимо запустить фоновый процесс проверки имени пользователя, пока он вводит пароль. Чтобы сохранить стандартное поведение переключения фокуса, присущее ImeAction.Next, наряду с этой собственной валидацией, вызывается функция performDefaultAction(). Вызов performDefaultAction() неявно запускает базовую систему управления фокусом, чтобы переместить фокус на следующий подходящий элемент пользовательского интерфейса, сохраняя ожидаемый поток навигации.
Создайте поле для ввода пароля
SecureTextField – это composable-функция, созданная на основе текстовых полей, зависящих от состояния, и предназначенная для создания поля пароля. Для создания текстовых полей паролей рекомендуется использовать SecureTextField, так как он по умолчанию скрывает вводимые символы и отключает действия вырезания и копирования.
У SecureTextField есть textObfuscationMode, который управляет тем, как пользователь видит ввод символов. textObfuscationMode имеет следующие варианты:
Hidden– скрывает все входные данные. Режим работы по умолчанию на компьютерах.
Visible– показывает все входные данные.
RevealLastTyped: скрывает все символы, кроме последнего. Это режим работы по умолчанию на мобильных устройствах.
Дополнительные ресурсы
- Автоматическое форматирование номера телефона в текстовом поле
- Показ или скрытие пароля по выбору пользователя
- Проверка ввода по мере набора текста