Барьеры 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
:
Здесь мы видим, что box3 действительно получает все доступное пространство. Поскольку его ограничение start зависит от box1.end
, то при изменении ширины box1 также будет изменяться и ширина box3 автоматически. Например, если мы изменим ширину box1:
Box(Modifier.size(150.dp).background(Color.DarkGray).constrainAs(box1) { ...
то автоматически изменится ширина box3:
Однако от 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: