Image и TextField

Добавляем на экран картинки через Image и поле ввода через TextField с управляемым состоянием.

Image рисует картинку или иконку, TextField — поле ввода, чьё значение управляется состоянием снаружи.

Image: картинки и иконки

Image показывает графику. Источник передают через painter, а описание для доступности — через contentDescription:

Image(
    painter = painterResource(id = R.drawable.logo),
    contentDescription = "Логотип приложения",
    modifier = Modifier.size(120.dp)
)

Параметр contentDescription читают программы для незрячих (screen reader). Если картинка чисто декоративная, туда передают null. Параметр contentScale управляет тем, как изображение вписывается в отведённую область (например, ContentScale.Crop обрежет лишнее).

TextField: ввод текста

Поле ввода в Compose — управляемое. Оно не хранит текст внутри себя; вы передаёте текущее значение и обработчик изменений (вспомните state hoisting):

@Composable
fun SearchBox() {
    var query by remember { mutableStateOf("") }
    TextField(
        value = query,
        onValueChange = { query = it },
        label = { Text("Поиск") }
    )
}

Когда пользователь печатает, вызывается onValueChange с новой строкой, вы записываете её в состояние, Compose перерисовывает поле — и в нём появляется введённый символ. Без обновления состояния поле выглядело бы «замороженным»: пользователь жмёт клавиши, а в поле ничего не появляется. Этот эффект — почти всегда признак забытого обновления состояния в onValueChange. Material 3 предлагает два варианта поля: TextField с заливкой и OutlinedTextField с рамкой — выбор чисто визуальный, API у них одинаковый.

Полезные параметры TextField

ПараметрНазначение
labelподпись поля
placeholderподсказка в пустом поле
singleLineзапрет переноса на новую строку
visualTransformationмаскировка (например, пароль)

Как работает под капотом

Каждое нажатие клавиши — это событие. TextField не меняет текст сам: он зовёт ваш onValueChange, передавая желаемое новое значение. Вы — владелец состояния — решаете, принять его, отфильтровать или преобразовать. Это тот же однонаправленный поток данных: значение вниз, событие вверх.

Частые ошибки

  • Не обновлять состояние в onValueChange — поле не реагирует на ввод, кажется сломанным.
  • Забывать contentDescription у важных картинок — приложение становится недоступным для незрячих.
  • Пытаться «прочитать» текст из TextField напрямую — текст живёт в вашем состоянии, а не в виджете.

Итог

  • Image рисует графику; contentDescription важен для доступности.
  • TextField управляемый: значение и onValueChange приходят снаружи.
  • Без обновления состояния в onValueChange поле ввода не работает.
Проверьте себя
1. Почему TextField называют управляемым (controlled) компонентом?
AОн сам хранит и меняет свой текст
BЕго значение приходит снаружи через value, а изменения сообщаются через onValueChange
CОн управляется только из XML
DОн работает без состояния
2. Зачем у Image параметр contentDescription?
AДля задания размера
BДля доступности: его читают программы для незрячих
CДля выбора формата файла
DДля кеширования изображения