Контейнеры компоновки

Последнее обновление: 30.03.2024

В Jetpack Compose за расположение и компоновку компонентов в приложении отвечает специальный компонент - Layout. Он имеет следующую сигнатуру:

@Composable inline fun Layout(
    content: @Composable () -> Unit,
    modifier: Modifier = Modifier,
    measurePolicy: MeasurePolicy
)

Он имеет следующие параметры:

  • content: Composable-функция, которая хранит все вложенные компоненты

  • modifier: объект Modifier, которые устанавливает функции-модификаторы, применяемые для стилизации компонента

  • measurePolicy: объект, который отвечает за вычисление размеров компонентов и их определение их расположения

Создание своего алгоритма вычисления размеров компонентов внутри компонента-контейнера, должная компоновка вложенных компонентов представляют трудоемкую работу, поэтому фреймворк Compose предоставляет ряд встроенных компонентов-контейнеров, которые автоматически выполняют эту работу. Основными из них являются Box, Row и Column. Рассмотрим эти контейнеры.

Box

Компонент Box является наиболее простым контейнером, позволяя позиционировать вложенное содержимое. Он представляет некоторую область экрана. Функция данного компонента принимает четыре параметра:

@Composable
inline fun Box(
    modifier: Modifier = Modifier,
    contentAlignment: Alignment = Alignment.TopStart,
    propagateMinConstraints: Boolean = false,
    content: @Composable BoxScope.() -> Unit
): @Composable Unit
  • modifier: объект Modifier, который позволяет настроить внешний вид и поведение компонента с помощью модификаторов

  • contentAlignment: объект Alignment, который устанавливает расположение компонента. По умолчанию имеет значение Alignment.TopStart (расположение вначале контейнера в верхнем углу)

  • propagateMinConstraints: значение типа Boolean, который указывает, надо ли применять к содержимому ограничения по минимальным размерам. По умолчанию равно false (ограничения не применяются)

  • content: объект интерфейса BoxScope, который представляет вложенное содержимое

Modifier

Контейнер Box может использоваться как самодостаточный компонент без какого-либо вложенного содержимого:

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.size
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 {
            Box(
                modifier = Modifier.size(300.dp, 250.dp).background(Color.Blue)
            )
        }
    }
}

Для установки визуальных свойств объекта Box применяется свойство modifier, которое представляет объект Modifier, рассмотренный в прошлой главе. Как и для других компонентов, для компонента Box мы можем вызвать функцию size(), которая принимает ширину и длину контейнера - в данном случае ширина 300 единиц и высота 250 единиц.

Modifier.size(300.dp, 250.dp)

Эта функция опять же возвращает объект Modifier, у которого далее вызыватся другая функция - background(), которая устанавливает фоновый цвет контейнера - в данном случае синий цвет или значение Color.Blue

Modifier.size(300.dp, 250.dp).background(Color.Blue)

В итоге мы увидим на экране синюю прямоугольную область размером 300 x 250.

Modifier и контейнер Box в Jetpack Compose и Kotlin в Android

Установка размеров Box

По умолчанию Box занимает те размеры на экране, которые необходимы, чтобы вместить содержимое. Но выше в Box никакого вложенного содержимого не было, поэтому чтобы установить размеры, применялся объект Modifier и его функция size()

Modifier.size(300.dp, 250.dp)

Если необходимо растянуть элемент по всей ширине и длине экрана, то, как и в общем случае, применяется функция - fillMaxSize():

Modifier.fillMaxSize().background(Color.Blue)

Позиционирование внутри Box

Например, определим простейший элемент Box с вложенным элементом Text:

package com.example.helloapp

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Box
import androidx.compose.material3.Text
import androidx.compose.ui.unit.sp


class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            Box {
                Text("Hello METANIT.COM", fontSize = 28.sp,)
            }
        }
    }
}

Здесь мы видим, что вложенный компонент Text позиционируется в левом верхнем углу контейнера Box.

Контейнер Box в Jetpack Compose и Kotlin в Android

Есть три причины подобного позиционирования

  • Элемент Box сам по умолчанию располагается в верхнем левом углу устройства

  • Для Box не задано размеров, он будет стремиться занять пространство, необходимое для вложенного содержимого.

  • Если вложенное содержимое меньше размеров контейнера Box, то для его позиционирования внутри Box будет использоваться настройка contentAlignment. А по умолчанию применяет значение Alignment.TopStart (расположение вначале контейнера в верхнем углу)

contentAlignment

Для позиционирования внутри Box данный компонент определяет параметр contentAlignment, которому передаются свойства объекта Alignment:

  • Alignment.BottomCenter: внизу по центру

  • Alignment.BottomEnd: внизу в конце

  • Alignment.BottomStart: внизу в начале

  • Alignment.Center: по центру по вертикали и горизонтали

  • Alignment.CenterEnd: по центру про вертикали и в конце по горизонтали

  • Alignment.CenterStart: по центру про вертикали и в начале по горизонтали

  • Alignment.TopCenter: вверху по центру

  • Alignment.TopEnd: вверху в конце

  • Alignment.TopStart: вверху в начале

Здесь для определения расположения применяются такие слова как "начало" (Start) и "конец" (End). В зависимости от яхыка системы и системы письма - правосторонняя или левосторонняя начало и конец как может находиться справа, так и слева. Например, для подавляющего числа языков (в том числе русского) начало находится слева, а конец - справа.

Например, расположим вложенные элементы по центру:

package com.example.helloapp

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Box
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 {
            Box(
                contentAlignment = Alignment.Center,
                modifier = Modifier.fillMaxSize()
            ){
                Text("Hello METANIT.COM", fontSize = 28.sp,)
            }
        }
    }
}

Значение Alignment.Center указывает, что содержимое будет позиционироваться по центру как по горизонтали, так и по вертикали. А чтобы Box был растянут по всей площади экрана, применяется модификатор Modifier.fillMaxSize():

Позиционирование в контейнере Box в Jetpack Compose и Kotlin в Android, contentAlignment

Наложение компонентов

Если Box содержит несколько вложенных компонентов, то умолчанию они будут накладываться друг на друга в порядке следования (последний компонент располагается поверх предыдущих)

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.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material3.Text
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp


class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            Box( modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center )
            {
                Box(modifier = Modifier.background(Color.DarkGray).size(320.dp))
                Box(modifier = Modifier.background(Color.LightGray).size(280.dp))
                Text("Hello METANIT.COM", fontSize = 28.sp, modifier =Modifier.padding(10.dp))
            }
        }
    }
}
Вложенные компоненты в контейнере Box в Jetpack Compose и Kotlin в Android

Выравнивание вложенных компонентов

В Box мы можем задать расположение не только для всех вложенных компонентов в целом, но и для каждого компонента по отдельности. При определении компонентов внутри Box на компонентах можно определить модификатор align, который принимает вышерассмотренный объект Alignment и позволяет настроить положение каждого отдельного компонентов внутри Box:

package com.example.helloapp

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Box
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 {
            Box( modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center )
            {
                Text("TopStart", fontSize = 28.sp, modifier =Modifier.align(Alignment.TopStart))
                Text("TopEnd", fontSize = 28.sp, modifier =Modifier.align(Alignment.TopEnd))
                Text("Center", fontSize = 28.sp, modifier =Modifier.align(Alignment.Center))
                Text("BottomStart", fontSize = 28.sp, modifier =Modifier.align(Alignment.BottomStart))
                Text("BottomEnd", fontSize = 28.sp, modifier =Modifier.align(Alignment.BottomEnd))
            }
        }
    }
}
Расположение компонентов с помощью модификатора align в контейнере Box в Jetpack Compose и Kotlin в Android
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850