Как добавить внешний отступ для Box или любого элемента в Jetpack Compose
Что проверяют
Знаете ли вы, что в Compose нет отдельного margin, и понимаете ли, что порядок модификаторов меняет результат. Следом обычно дают цепочку вроде padding().background().clickable() и просят сказать, где окажется фон и какая область будет кликабельной.
Как отвечать
Внешний и внутренний отступ в Compose делает один и тот же Modifier.padding, разницу задаёт его место в цепочке. Модификаторы применяются слева направо, каждый оборачивает всё, что правее:
Box(
Modifier
.padding(16.dp)
.background(Color.LightGray)
.padding(8.dp)
)Первый padding работает как внешний отступ: фон начинается уже после него. Второй работает как внутренний и отодвигает содержимое от края фона. Если поставить clickable после первого padding, отступ в область нажатия не войдёт.
Что ещё назвать:
- варианты
padding:padding(horizontal = 16.dp, vertical = 8.dp),padding(start = 16.dp)с учётом RTL,absolutePaddingбез него. Отрицательные значения не принимаются; - расстояние между элементами:
Arrangement.spacedBy(8.dp)вRowиColumnилиSpacer, а не отступ на каждом ребёнке; - списки:
contentPaddingуLazyColumn, чтобы отступ прокручивался вместе с содержимым; - системные области:
ScaffoldотдаётinnerPadding, его нужно применить к контенту, а для edge-to-edge естьsafeDrawingPadding()иwindowInsetsPadding.
Правило для своих компонентов: принимайте параметр modifier: Modifier = Modifier и применяйте его к корневому элементу первым, тогда внешний отступ задаёт вызывающий код.
Где спотыкаются
Ищут Modifier.margin. Его нет, и ответ «если доступно» сразу выдаёт, что с Compose работали мало.
Используют offset вместо отступа. Он сдвигает элемент при размещении, но место в раскладке остаётся прежним, поэтому соседи не отодвигаются и элементы наезжают друг на друга.
Ставят padding после background или clickable и не понимают, почему фон или область нажатия шире ожидаемого. Всё решает порядок в цепочке.