Обработка ввода пользователя

TextField позволяет пользователям вводить и изменять текст. На этой странице описывается, как можно реализовать TextField , стилизовать ввод TextField и настроить другие параметры TextField , такие как параметры клавиатуры и визуальное преобразование пользовательского ввода.

Выберите реализацию TextField

Существует два уровня реализации TextField :

  1. TextField — это реализация Material Design. Мы рекомендуем вам выбрать эту реализацию, поскольку она соответствует рекомендациям Material Design :
  2. BasicTextField позволяет пользователям редактировать текст с помощью аппаратной или программной клавиатуры, но не предоставляет никаких украшений, таких как подсказка или заполнитель.

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

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

Редактируемое текстовое поле, содержащее слово

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

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

Редактируемое текстовое поле с фиолетовой рамкой и меткой.

Стиль TextField

TextField и BasicTextField имеют много общих параметров для их настройки. Полный список для TextField доступен в исходном коде TextField . Это неполный список некоторых полезных параметров:

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

Многострочное TextField с двумя редактируемыми строками и меткой.

Мы рекомендуем TextField вместо BasicTextField , если ваш дизайн требует Material TextField или OutlinedTextField . Однако BasicTextField следует использовать при создании проектов, которым не нужны украшения из спецификации материала.

Ввод стиля с помощью Brush API

Вы можете использовать API Brush для более сложного оформления вашего TextField . В следующем разделе описывается, как использовать кисть для добавления цветного градиента к входным данным TextField .

Дополнительные сведения об использовании Brush API для стилизации текста см. в разделе Включение расширенных стилей с помощью Brush API .

Реализация цветных градиентов с помощью TextStyle

Чтобы реализовать цветной градиент при вводе текста в TextField , установите выбранную кисть в качестве TextStyle для вашего TextField . В этом примере мы используем встроенную кисть с linearGradient для просмотра эффекта градиента радуги при вводе текста в TextField .

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

Использование buildAnnotatedString и SpanStyle вместе с линейным градиентом для настройки только части текста.
Рисунок 3. Использование buildAnnotatedString и SpanStyle вместе с linearGradient для настройки только части текста.

Установить параметры клавиатуры

TextField позволяет задавать параметры конфигурации клавиатуры, например раскладку клавиатуры, или включать автозамену, если она поддерживается клавиатурой. Некоторые параметры не могут быть гарантированы, если программная клавиатура не соответствует параметрам, представленным здесь. Вот список поддерживаемых вариантов клавиатуры :

  • capitalization
  • autoCorrect
  • keyboardType
  • imeAction

Формат ввода

TextField позволяет вам установить VisualTransformation для входного значения, например заменить символы на * для паролей или вставить дефисы каждые 4 цифры для номера кредитной карты:

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

Поле ввода текста пароля с замаскированным текстом

Дополнительные примеры доступны в исходном коде VisualTransformationSamples .

Чистый ввод

Обычной задачей при редактировании текста является удаление начальных символов или иное преобразование входной строки при каждом ее изменении.

В качестве модели вы должны предположить, что клавиатура может вносить произвольные и значительные изменения при каждом onValueChange . Это может произойти, например, если пользователь использует автозамену, заменяет слово смайликом или другие функции интеллектуального редактирования. Чтобы правильно справиться с этим, напишите любую логику преобразования, предполагая, что текущий текст, передаваемый в onValueChange не связан с предыдущими или следующими значениями, которые будут переданы в onValueChange .

Чтобы реализовать текстовое поле, в котором запрещены ведущие нули, вы можете сделать это, удалив все ведущие нули при каждом изменении значения.

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

Чтобы управлять положением курсора при очистке текста, используйте перегрузку TextFieldValue TextField как часть состояния.

Лучшие практики взаимодействия с государством

Ниже приведен ряд рекомендаций по определению и обновлению состояния TextField , чтобы предотвратить проблемы с вводом в вашем приложении.

  • Используйте MutableState для представления состояния TextField . Избегайте использования реактивных потоков, таких как StateFlow , для представления состояния TextField , поскольку эти структуры могут привести к асинхронным задержкам.

class SignUpViewModel : ViewModel() {

    var username by mutableStateOf("")
        private set

    /* ... */
}

  • Избегайте задержек при обновлении состояния : при вызове onValueChange обновляйте TextField синхронно и немедленно:

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

  • Где определить состояние : если ваше состояние TextField требует проверки бизнес-логики при вводе, правильно будет поднять состояние в вашу ViewModel . Если это не так, вы можете использовать компонуемые объекты или класс держателя состояния в качестве источника истины. Чтобы узнать больше о том, где поднять состояние, см. документацию по поднятию состояния .
{% дословно %} {% дословно %} {% дословно %} {% дословно %}