Барьеры

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

Барьеры ConstraintLayout создаются относительно определенной стороны одного или нескольких компонентов с помощью следующих функций:

  • createStartBarrier()

  • createEndBarrier()

  • createTopBarrier()

  • createBottomBarrier()

Каждой функции передается список компонентов, которым должен быть назначен барьер вместе с необязательным полем. В качестве результата функции возвращают ссылку на барьер, которую можно использовать для создания ограничений компонентов. Например:

val barrier = createEndBarrier(box1, box2, margin = 30.dp)

Эта строка создает вертикальный барьер (начальный и конечный барьеры вертикальны, а верхний и нижний — горизонтальные), расположенный на расстоянии 30dp от конца кнопок button1 и button2. Если box1 и box2 имеют разную ширину, барьер будет находиться на расстоянии 30dp от конца самого широкого компонента в любой момент времени. Например, возьмем следующую программу:

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.size
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.constraintlayout.compose.ConstraintLayout
import androidx.constraintlayout.compose.Dimension

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent{
            ConstraintLayout(Modifier.fillMaxSize()) {
                val (box1, box2, box3) = createRefs()
                Box(Modifier.size(120.dp).background(Color.DarkGray).constrainAs(box1) {
                    top.linkTo(parent.top, margin = 30.dp)
                    start.linkTo(parent.start, margin = 8.dp)
                })
                Box(Modifier.size(120.dp).background(Color.Red).constrainAs(box2) {
                    top.linkTo(box1.bottom, margin = 20.dp)
                    start.linkTo(parent.start, margin = 8.dp)
                })
                Box(Modifier.background(Color.Blue).constrainAs(box3) {
                    linkTo(parent.top, parent.bottom,topMargin = 8.dp, bottomMargin = 8.dp)
                    linkTo(box1.end, parent.end, startMargin = 30.dp,endMargin = 8.dp)
                    width = Dimension.fillToConstraints
                    height = Dimension.fillToConstraints
                })
            }
        }
    }
}

Здесь размер компонента box3 устанавливается таким, чтобы заполнять максимально доступное пространство, разрешенное его ограничениями. Это не только гарантирует, что компонент заполнит доступную высоту, но также позволит регулировать ширину в ответ на изменения размера box1 и box2. Для заполнения доступного пространства у box3 устанавливаются ограничения width и height на fillConstraints:

ConstraintLayout и барьеры в Jetpack Compose на Kotlin на Android

Здесь мы видим, что box3 действительно получает все доступное пространство. Поскольку его ограничение start зависит от box1.end, то при изменении ширины box1 также будет изменяться и ширина box3 автоматически. Например, если мы изменим ширину box1:

Box(Modifier.size(150.dp).background(Color.DarkGray).constrainAs(box1) { ...

то автоматически изменится ширина box3:

ConstraintLayout и barrier в Jetpack Compose на Kotlin на Android

Однако от box2 компонент box3 никак не зависит. Поэтому изменение ширины box2 никак не затронет box3. И чтобы размеры box3 автоматически изменялись как при изменении box1, так и при изменении box2, применим барьеры:

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.size
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.constraintlayout.compose.ConstraintLayout
import androidx.constraintlayout.compose.Dimension

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent{
            ConstraintLayout(Modifier.fillMaxSize()) {
                val (box1, box2, box3) = createRefs()
                val barrier = createEndBarrier(box1, box2)
                Box(Modifier.size(120.dp).background(Color.DarkGray).constrainAs(box1) {
                    top.linkTo(parent.top, margin = 30.dp)
                    start.linkTo(parent.start, margin = 8.dp)
                })
                Box(Modifier.size(150.dp).background(Color.Red).constrainAs(box2) {
                    top.linkTo(box1.bottom, margin = 20.dp)
                    start.linkTo(parent.start, margin = 8.dp)
                })
                Box(Modifier.background(Color.Blue).constrainAs(box3) {
                    linkTo(parent.top, parent.bottom,topMargin = 8.dp, bottomMargin = 8.dp)
                    linkTo(box1.end, parent.end, startMargin = 30.dp,endMargin = 8.dp)
                    start.linkTo(barrier, margin = 30.dp)
                    width = Dimension.fillToConstraints
                    height = Dimension.fillToConstraints
                })
            }
        }
    }
}

В данном случае создается вертикальный барьер по end для компонентов box1 и box2:

val barrier = createEndBarrier(box1, box2)

Далее устанавливаем этот барьер в качестве ограничения для начальной стороны для box3 со смещением в 30 пикселей:

start.linkTo(barrier, margin = 30.dp)

И теперь при изменении ширины box1 или box2 автоматически изменится ширина box3:

ConstraintLayout и барьеры как ограничения в Jetpack Compose на Kotlin на Android
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850