Контейнер Column позволяет выстроить вложенные компоненты в столбик. Функция Column принимает четыре параметра:
@Composable inline fun Column( modifier: Modifier = Modifier, verticalArrangement: Arrangement.Vertical = Arrangement.Top, horizontalAlignment: Alignment.Horizontal = Alignment.Start, content: @Composable ColumnScope.() -> Unit ): @Composable Unit
modifier: объект Modifier, который позволяет настроить внешний вид и поведение компонента
verticalArrangement: объект Arrangement.Vertical, который устанавливает выравнивание компонента по вертикали.
По умолчанию имеет значение Arrangement.Top
(расположение в верху)
horizontalAlignment: объект Alignment.Horizontal, который устанавливает выравнивание компонента по
горизонтали. По умолчанию имеет значение Alignment.Start
(расположение в начале - слева для языков с левосторонним письмом и справа для языков с правосторонним письмом)
content: объект интерфейса BoxScope, который представляет вложенное содержимое
Так, изменим код MainActivity.kt следующим образом:
package com.example.helloapp import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.foundation.layout.Column import androidx.compose.material3.Text import androidx.compose.ui.unit.sp class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { Column { Text("Kotlin", fontSize = 28.sp) Text("Java", fontSize = 28.sp) Text("JavaScript", fontSize = 28.sp) Text("Python", fontSize = 28.sp) } } } }
Если ни у одного вложенного компонента НЕ указан вес, Column занимает то пространство, которое необходимо, чтобы вместить вложенные компоненты. Если подобный размер контейера нежелателен, то можно задать конкретный размер с помощью модификатора Modifier.height:
Column(modifier = Modifier.height(550.dp))
С помощью модификатора Modifier.fillMaxHeight можно растянуть контейер по всей длине экрана.
Column(modifier = Modifier.fillMaxSize())
Если как минимум для одного вложенного компонента указан вес, то в модификаторе Modifier.fillMaxHeight нет смысла. Однако в этот случае по прежнему можно использовать модификаторы Modifier.height и Modifier.size для ограничения длины контейера.
Если высота контейера Column больше суммы высот его вложенных компонентов, то для позиционирования этих компонентов может применяться параметр verticalArrangement, который может принимать следующие значения:
Arrangement.Center: расположение по центру
Arrangement.Bottom: расположение внизу
Arrangement.Top: расположение вверху
Arrangement.SpaceAround: компоненты равномерно распределяются по всей высоте с равномерными отступами между элементами, при этом отступы между первым и последним элементами и границами контейнера равен половине отступов между элементами
Arrangement.SpaceBetween: компоненты равномерно распределяются по всей высоте с равномерными отступами между элементами, при этом первый и последний элементы прижимаются к границам контейнера
Arrangement.SpaceEvenly: компоненты равномерно распределяются по всей высоте с равномерными отступами между элементами, при этом отступы между первым и последним элементами и границами контейнера равны отступам между элементами
Например:
package com.example.helloapp import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { Column(modifier = Modifier.fillMaxSize(), verticalArrangement = Arrangement.SpaceBetween ) { Box(modifier = Modifier.background(Color.Red).fillMaxWidth().height(100.dp)) Box(modifier = Modifier.background(Color.DarkGray).fillMaxWidth().height(100.dp)) Box(modifier = Modifier.background(Color.Blue).fillMaxWidth().height(100.dp)) } } } }
Параметр horizontalAlignment
позволяет выровнить содержимое вложенных компонентов. Этому параметру можно передать одно из следующих значений:
Alignment.Start
: выравнивание в начале (по умолчанию)
Alignment.End
: выравнивание в конце
Alignment.CenterHorizontally
: выравнивание по центру
Начало и конец в зависимости от направления написания для текущего языка может означать левый или правый край. Например:
package com.example.helloapp import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.material3.Text import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.sp class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { Column(horizontalAlignment = Alignment.End, modifier = Modifier.fillMaxSize()) { Text("Kotlin", fontSize = 28.sp) Text("Java", fontSize = 28.sp) Text("JavaScript", fontSize = 28.sp) Text("Python", fontSize = 28.sp) } } } }
Здесь идет выравнивание по правому краю:
Поскольку вложенные компоненты в Row определяются внутри ColumnScope, то ColumnScope предоставляет вложенным компонентам еще ряд модификаторов:
align(): определяет выравнивание компонента по вертикали и может принимать значения:
Alignement.Start
: выравнивание по началу контейнера (в зависимости от ориентации это правая или левая сторона)
Alignement.CenterHorizontally
: выравнивание по центру
Alignement.End
: выравнивание по концу контейнера (в зависимости от ориентации это правая или левая сторона)
alignBy(): выравнивает компонент относительно определенной вертикальной линии
weight(): задает вес компонента
Например, установка выравнивания по горизонтали отдельно для каждого компонента с помощью модификатора align:
package com.example.helloapp import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.material3.Text import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.sp class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { Column(modifier = Modifier.fillMaxSize()) { Text("Start", fontSize = 28.sp, modifier = Modifier.align(Alignment.Start)) Text("Center", fontSize = 28.sp, modifier = Modifier.align(Alignment.CenterHorizontally)) Text("End", fontSize = 28.sp, modifier = Modifier.align(Alignment.End)) } } } }
Вес (weight) внутри Column позволяет назначить вложенным компонентам высоту в соответствии с некоторым коэффициентом. Для указания веса применяется модификатор ColumnScope.weight. Стоит учитывать, что если контейнер Column обеспечивает вертикальную прокрутку или располагается в контейере, который предполагает вертикальную прокрутку, то веса компонентов игнорируются, поскольку общее пространство по вертикали условно бесконечно.
package com.example.helloapp import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { Column { Box(modifier = Modifier.background(Color.Red).fillMaxWidth().weight(1f)) Box(modifier = Modifier.background(Color.DarkGray).fillMaxWidth().weight(3f)) Box(modifier = Modifier.background(Color.Blue).fillMaxWidth().weight(2f)) } } } }
Обратите внимание, как передается вес:
Modifier.background(Color.Red).fillMaxWidth().weight(1f)
В качестве веса в функцию weight()
фактически передается доля пространства в единицах f.
Так, первый элемент Box имеет вес 1f
, второй - 3f
, третий - 2f
. Соовокупный вес всех комонентов, таким образом, будет
1f + 3f + 2f = 6f. И в итоге получится, что первый элемент получит от пространства 1f/6f часть или одну шестую. Второй элемент - 3f/6f или половину простанства,
а третий - 2f/6f или одну третью пространства. Таким образом будет распределено пространство по вертикали между вложенными элементами.
Однако веса управляют только распределением пространства по вертикали, то есть для установки высоты. Ширина же устанавливается либо исходя из явно
указанных значений ширины, либо исходя из вложенного содержимого. В данном случае по умолчанию вложенные элементы Box получат нулевую ширину, поэтому,
чтобы их бло видно, в данном случае растягивает элементы по всей ширине с помощью модификатора fillMaxWidth()
.
Стоит отметить, что модификатор weight() может принимать второй параметр - булевое значение, которое указывает, будет ли
ему выделяться пространство в соответствии с его весом. Если этот параметр равен false
, то его вес не учитывается:
Box(modifier = Modifier.background(Color.Yellow).fillMaxWidth().weight(3f, fill=false))
Если у компонента не указан вес, то контейер сначала запрашивает его предпочтительную высоту. Затем оставшее простанство распределяется между компонентами, для которых указан вес, в соответствии с их весом.
package com.example.helloapp import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { Column { Box(modifier = Modifier.background(Color.Red).fillMaxWidth().weight(1f)) Box(modifier = Modifier.background(Color.DarkGray).fillMaxWidth().height(150.dp)) Box(modifier = Modifier.background(Color.Blue).fillMaxWidth().weight(2f)) } } } }
Здесь для второго элемента Box установлена высота в 150 единиц, а для остальных установлены веса - 1f и 2f. Таким образом, получится, что от всей длины контейера Column (а он будет растягиваться на весь экран) второй элемент получит высоту в 150 единиц. Оставшееся пространство затем будет распределено между первым и третим элементами в соответствии с их весами.