Box — это composable-функция в Jetpack Compose для размещения дочерних элементов друг над другом по принципу слоёв. В отличие от Row и Column, Box накладывает элементы на одну область, что позволяет создавать текстуры, бейджи и кастомные индикаторы. По данным Google Android Documentation, 2025, Box является одним из трёх базовых контейнеров Compose и обеспечивает гибкое управление слоями с помощью Modifier.align и Modifier.zIndex.
Главное
Box — это composable-функция, которая располагает дочерние элементы в одной области, накладывая их друг на друга. Первый дочерний элемент отрисовывается внизу, последний — сверху. По умолчанию Box подстраивается под размер самого большого дочернего элемента.
В отличие от Row и Column, Box не выстраивает элементы последовательно — все дочерние элементы занимают одну и ту же область и могут перекрывать друг друга. Это делает Box незаменимым для композиции слоёв интерфейса.
Размер Box определяется по правилу: если ни один дочерний элемент не имеет фиксированного размера, Box сворачивается до минимального размера. Если хотя бы один дочерний элемент имеет Modifier.fillMaxSize, Box расширяется до максимального.
По данным Android Developers Blog, 2024, Box — это наиболее эффективный контейнер в Compose для случаев, когда элементы не требуют последовательного расположения. Box не выполняет дополнительных измерений для позиционирования, в отличие от Row и Column.
Box принимает параметры modifier, contentAlignment и propagateMinConstraints. Все дочерние элементы передаются в content-блоке, где каждый может иметь собственные модификаторы.
@Composable
fun BoxExample() {
Box(
modifier = Modifier.size(200.dp),
contentAlignment = Alignment.Center
) {
Box(
modifier = Modifier.fillMaxSize().background(Color.Blue)
)
Text(
text = "Hello",
color = Color.White
)
}
}
contentAlignment — это параметр Box, который задаёт выравнивание по умолчанию для всех дочерних элементов. Если не указан, используется Alignment.TopStart — элементы располагаются в левом верхнем углу контейнера.
Modifier.align позволяет переопределить выравнивание для конкретного дочернего элемента независимо от contentAlignment. Например, Box с Alignment.Center может содержать элемент с Modifier.align(Alignment.BottomEnd), который будет прижат к правому нижнему углу.
По данным Material Design Guidelines, 2025, Modifier.align полезен для позиционирования бейджей и значков поверх фоновых изображений. Это позволяет задать общее выравнивание для всего содержимого Box и переопределить его для отдельных элементов.
| Значение | Позиция в Box | Пример применения |
|---|---|---|
| TopStart | Левый верхний угол | Иконка в углу карточки |
| TopCenter | Верхний центр | Заголовок над изображением |
| Center | Центр контейнера | Текст по центру фона |
| BottomEnd | Правый нижний угол | Счётчик уведомлений на иконке |
| BottomCenter | Нижний центр | Подпись под изображением |
В этом примере Box содержит фоновое изображение и бейдж в правом нижнем углу. Modifier.align(BottomEnd) позиционирует бейдж независимо от contentAlignment всего Box.
@Composable
fun BadgeExample() {
Box(
modifier = Modifier.size(120.dp),
contentAlignment = Alignment.Center
) {
Box(
modifier = Modifier.size(100.dp).background(Color.Gray)
)
Box(
modifier = Modifier
.size(30.dp)
.align(Alignment.BottomEnd)
.background(Color.Red, CircleShape)
)
}
}
Modifier.zIndex управляет порядком отрисовки элементов внутри Box. По умолчанию элементы отрисовываются в порядке объявления — первый элемент внизу, последний наверху. zIndex переопределяет этот порядок.
Элемент с zIndex 2.0f отрисовывается поверх элемента с zIndex 1.0f, независимо от их порядка в коде. Отрицательные значения zIndex опускают элемент ниже остальных. По данным Android Developers, 2024, zIndex влияет только на порядок отрисовки, но не на обработку событий касания.
zIndex особенно полезен в анимациях и draggable-компонентах, где элемент должен временно подниматься над остальными. Например, при перетаскивании карточки её zIndex увеличивается, чтобы она не перекрывалась соседними элементами.
@Composable
fun ZIndexExample() {
Box(modifier = Modifier.size(150.dp)) {
Box(modifier = Modifier.size(80.dp)
.align(Alignment.TopStart)
.zIndex(2.0f)
.background(Color.Green))
Box(modifier = Modifier.size(100.dp)
.align(Alignment.Center)
.zIndex(1.0f)
.background(Color.Blue))
}
}
Box широко применяется для наложения текста на изображение. Фоновое изображение размещается первым, затем текст с Modifier.align для позиционирования поверх фона.
@Composable
fun ImageWithOverlay() {
Box(modifier = Modifier.fillMaxWidth().height(200.dp)) {
Image(
painter = painterResource(R.drawable.photo),
contentDescription = "Photo",
modifier = Modifier.fillMaxSize(),
contentScale = ContentScale.Crop
)
Box(
modifier = Modifier.fillMaxSize()
.background(Color.Black.copy(alpha = 0.4f))
)
Text(
text = "Title",
color = Color.White,
modifier = Modifier.align(Alignment.BottomStart)
.padding(16.dp)
)
}
}
Второй пример — Box для создания индикатора загрузки. Box занимает всю область экрана, а CircularProgressIndicator центрируется по contentAlignment.
@Composable
fun LoadingOverlay() {
Box(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center
) {
CircularProgressIndicator(
modifier = Modifier.size(48.dp)
)
}
}
Box по умолчанию подстраивается под размер содержимого. Если дочерние элементы имеют разные размеры, Box принимает размер самого большого элемента. При отсутствии дочерних элементов Box сворачивается до минимального размера.
Modifier.clipToBounds ограничивает отрисовку дочерних элементов границами Box. Без этого модификатора дочерние элементы могут выходить за пределы Box. По данным Material Design Guidelines, 2025, clipToBounds обязателен при использовании Modifier.scale или Modifier.graphicsLayer внутри Box.
propagateMinConstraints — это параметр Box, который передаёт минимальные ограничения размеров дочерним элементам. Если установлен в true, дочерние элементы не могут быть меньше минимального размера Box. Это поведение важно при создании кастомных контейнеров с фиксированными минимальными размерами.
Часто задаваемые вопросы
Box накладывает элементы друг на друга, а Row и Column выстраивают их последовательно. Box подходит для слоёв и перекрытий, Row — для горизонтальных рядов, Column — для вертикальных списков.
Используйте Modifier.align для конкретного дочернего элемента. Этот модификатор переопределяет contentAlignment, заданный для всего Box. Например, Modifier.align(Alignment.BottomEnd) прижмёт элемент к правому нижнему углу.
Задайте Box с Modifier.size и Modifier.background, а contentAlignment установите в Alignment.Center. Текст внутри Box будет автоматически центрирован без дополнительных модификаторов.
propagateMinConstraints передаёт минимальные ограничения размеров Box дочерним элементам. При значении true дочерние элементы не могут быть меньше минимального размера, заданного для Box через Modifier.size или Modifier.constrain.
Порядок объявления элементов в Box определяет их визуальный порядок: первый элемент внизу, последний — наверху. Для тонкого управления используйте Modifier.zIndex — элемент с большим значением отрисовывается поверх остальных.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также