Освой Android играючи
/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей - и все становится ясно. */
John Robbins, Debugging Applications, Microsoft Press, 2000
10-й курс/Закрытая зона
Обновлено 31.07.2023, 20.02.2024, 02.05.2024, 2 мая 2025
Функция TextField позволяет создать стандартное текстовое поле для ввода текста, знакомое нам по EditText.
Определение функции.
@OptIn(markerClass = {androidx. compose. material3.ExperimentalMaterial3Api::class})
@Composable
public fun TextField(
value: String,
onValueChange: (String) -> Unit,
modifier: Modifier = Modifier,
enabled: Boolean = true,
readOnly: Boolean = false,
textStyle: TextStyle = LocalTextStyle. current,
label: @Composable() (() -> Unit)? = null,
placeholder: @Composable() (() -> Unit)? = null,
leadingIcon: @Composable() (() -> Unit)? = null,
trailingIcon: @Composable() (() -> Unit)? = null,
prefix: @Composable() (() -> Unit)? = null,
suffix: @Composable() (() -> Unit)? = null,
supportingText: @Composable() (() -> Unit)? = null,
isError: Boolean = false,
visualTransformation: VisualTransformation = VisualTransformation. None,
keyboardOptions: KeyboardOptions = KeyboardOptions. Default,
keyboardActions: KeyboardActions = KeyboardActions. Default,
singleLine: Boolean = false,
maxLines: Int = if (singleLine) 1 else Int. MAX_VALUE,
minLines: Int = 1,
interactionSource: MutableInteractionSource? = null,
shape: Shape = TextFieldDefaults. shape,
colors: TextFieldColors = TextFieldDefaults. colors()
): Unit
Создадим текстовое поле для ввода текста. Для простого примера ограничимся параметрами label и placeholder (при желании параметры можно убрать, чтобы оставить только пустое поле без украшений).
@Composable
fun Content(modifier: Modifier = Modifier) {
Column(
modifier
.fillMaxSize()
.padding(16.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Top
) {
var text by remember { mutableStateOf("") } // пустая строка
TextField(
value = text,
onValueChange = { text = it },
label = { Text("Введите имя кота") },
placeholder = { Text(text = "Барсик") },
modifier = modifier.padding(4.dp)
)
}
}
Если вам нужно ввести заранее текст, то просто добавьте его в text.
var text by remember { mutableStateOf("Здесь написано Кот") }
Ниже показано текстовое поле в трёх различных состояниях:

Текущий текст хранится в параметре value. При вводе символов срабатывает метод обратного вызова onValueChange(), который позволяет получить новый текст.
Длину и высоту поля можно установить через Modifier.width().height().
modifier = Modifier.fillMaxWidth()
modifier = Modifier
.width(250.dp)
.wrapContentHeight(align = Alignment.CenterVertically)
modifier = Modifier
.requiredWidth(315.dp)
.height(150.dp)
modifier = Modifier
.fillMaxWidth(0.8F)
.height(100.dp)
Задать другую форму для текстового поля можно через модификатор border.
@Composable
fun Content(modifier: Modifier = Modifier) {
Column(
modifier
.background(Color(0xFFEDEAE0))
.fillMaxSize()
.padding(16.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(80.dp)
) {
// Spacer(modifier = modifier.height(60.dp))
var text by remember { mutableStateOf(TextFieldValue()) }
val gradient = listOf(Color.Red, Color.Yellow, Color.Green)
TextField(
value = text,
onValueChange = { text = it },
modifier = modifier
.padding(4.dp)
.border(
border = BorderStroke(
brush = Brush.linearGradient(gradient),
width = 2.dp
),
shape = CutCornerShape(12.dp)
),
label = {
Text(text = "Введите имя кота")
},
placeholder = { Text(text = "Барсик") },
)
}
}
Если запустить этот пример, то можно увидеть, полоску для индикации получения фокуса. Как её убрать - в примере ниже.

В параметре colors можно настраивать различные цвета (более 40 параметров!). Изменим цвет фона и текста.
TextField(
...
modifier = Modifier.padding(4.dp),
colors = TextFieldDefaults.colors(
focusedContainerColor = Color.Magenta,
focusedTextColor = Color.Green
)
)
У текстового поля внизу идёт тонкая полоска для индикации получения фокуса. Можем убрать её, сделав прозрачной. Либо можете установить свои цвета, чтобы подчеркнуть индивидуальность.
colors = TextFieldDefaults.colors(
focusedIndicatorColor = Color.Transparent,
unfocusedIndicatorColor = Color.Transparent
)
Для примера с параметром isError (см. ниже) можно применить цвета для индикации ошибки.
colors = TextFieldDefaults.textFieldColors(
errorIndicatorColor = Color.Magenta,
errorCursorColor = Color.Magenta,
errorLabelColor = Color.Magenta
)
В начале и в конце текстового поля можно поместить значок.
@Composable
fun Content(modifier: Modifier = Modifier) {
Column(
modifier
.fillMaxSize()
.padding(16.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Top
) {
var text by remember { mutableStateOf("") }
TextField(
value = text,
onValueChange = { text = it },
modifier = modifier.padding(4.dp),
label = { Text("Купить для кота") },
leadingIcon = {
Icon(
imageVector = Icons.Filled.Star,
contentDescription = null,
tint = Color.Magenta
)
},
trailingIcon = {
// По аналогии
}
)
}
}
В Compose есть готовый компонент SearchBar, но вы можете самостоятельно создать похожий элемент, добавив значок.
@Composable
fun SearchBar(
modifier: Modifier = Modifier
) {
TextField(
value = "",
onValueChange = {},
leadingIcon = {
Icon(
imageVector = Icons.Default.Search,
contentDescription = null
)
},
colors = TextFieldDefaults.colors(
unfocusedContainerColor = MaterialTheme.colorScheme.surface,
focusedContainerColor = MaterialTheme.colorScheme.surface
),
placeholder = {
Text(stringResource(R.string.placeholder_search))
},
modifier = modifier
.fillMaxWidth()
.heightIn(min = 56.dp)
)
}
Число строк в текстовом поле можно установить через параметр maxLines.
В версии Compose 1.4 у компонентов TextField, BasicTextField, OutlinedTextField появился новый параметр minLines.
Чтобы привлечь внимание пользователя к неправильным символам в текстовом поле, можно использовать специальный параметр isError и перевести поле в "ошибочное" состояние. В этом случае нижняя полоска меняет свой цвет.
@Composable
fun Content(modifier: Modifier = Modifier) {
Column(
modifier
.fillMaxSize()
.padding(16.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(80.dp)
) {
var text by remember { mutableStateOf("") }
var errorState by remember { mutableStateOf(false) }
var errorMessage by remember { mutableStateOf("") }
TextField(
value = text,
onValueChange = {
text = it
when {
text.isEmpty() -> {
errorState = true
errorMessage = "Поле не может быть пустым"
}
text.startsWith("0") -> {
errorState = true
errorMessage = "Имя не может начинаться с 0"
}
else -> {
errorState = false
errorMessage = ""
}
}
},
modifier = modifier.padding(4.dp),
label = {
Text(
text = if (errorState) errorMessage
else "Введите имя кота"
)
},
placeholder = { Text(text = "Барсик") },
isError = errorState
)
}
}

Упрощённый вариант - нужно ввести имя, которое состоит из не менее трёх символов, но не больше девяти. При недопустимых вариантах полоска будет менять свой цвет на красный.
{
var textState by remember { mutableStateOf(TextFieldValue()) }
var errorState by remember { mutableStateOf(false) }
TextField(
value = textState,
onValueChange = {
textState = it
errorState = it.text.length < 3 || it.text.length > 9
},
label = {
Text(text = "Введите имя кота")
},
placeholder = { Text(text = "Барсик") },
isError = errorState,
)
}
Клавиатура может иметь специальные значки для разных случаев, например, значок поиска и значок завершения действия "Done".
Значок "Done" полезен, когда на экране несколько текстовых полей и пользователь должен последовательно переходить с одного на другой после заполнения данных.
@Composable
fun Content(modifier: Modifier = Modifier) {
Column(
modifier
.fillMaxSize()
.padding(16.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(80.dp)
) {
var text by remember { mutableStateOf(TextFieldValue()) }
val focusManager = LocalFocusManager.current
TextField(
value = text,
onValueChange = {
text = it
},
modifier = modifier.padding(4.dp),
label = {
Text(text = "Введите имя кота")
},
placeholder = { Text(text = "Барсик") },
keyboardOptions = KeyboardOptions(
imeAction = ImeAction.Done
),
keyboardActions = KeyboardActions(
onDone = {
focusManager.clearFocus()
println(text)
}
)
)
}
}
Также доступны другие варианты. Заменим на Go (по аналогии попробуйте Send, Search):
keyboardOptions = KeyboardOptions(
imeAction = ImeAction.Go
),
keyboardActions = KeyboardActions(
onGo = {
focusManager.clearFocus()
println(textState.text)
}
)
Вы вошли на сайт, как гость.
Необходимо зарегистрироваться, чтобы прочитать статью
