기본적인 사용법에 이어 이번엔 chain과 barrier에 대해 알아보자!
1. Chain
constraintLayout의 기능 중 하나로 chain 기능이 있다.
이것을 compose로 구현해 보자!
ConstraintLayout(Modifier.size(60.dp)) {
val (box1, box2, box3) = createRefs()
Box(
modifier = Modifier
.size(10.dp)
.background(Color.Red)
.constrainAs(box1) {
top.linkTo(parent.top)
}
)
Box(
modifier = Modifier
.size(10.dp)
.background(Color.Yellow)
.constrainAs(box2) {
top.linkTo(parent.top)
}
)
Box(
modifier = Modifier
.size(10.dp)
.background(Color.Green)
.constrainAs(box3) {
top.linkTo(parent.top)
}
)
createHorizontalChain(box1, box2, box3)
createVerticalChain(box1, box2, box3)
}
compose에서는 createHorizontalChain, createVerticalChain을 통해 만들어줘야 한다.
그리고 ChainStyle을 지정해 그림 1과 같이 만들 수 있다.
ChainStyle의 값은 아래와 같이 있다.
@Immutable
class ChainStyle internal constructor(
internal val style: SolverChain,
internal val bias: Float? = null
) {
companion object {
/**
* A chain style that evenly distributes the contained layouts.
*/
@Stable
val Spread = ChainStyle(SolverChain.SPREAD)
/**
* A chain style where the first and last layouts are affixed to the constraints
* on each end of the chain and the rest are evenly distributed.
*/
@Stable
val SpreadInside = ChainStyle(SolverChain.SPREAD_INSIDE)
/**
* A chain style where the contained layouts are packed together and placed to the
* center of the available space.
*/
@Stable
val Packed = Packed(0.5f)
/**
* A chain style where the contained layouts are packed together and placed in
* the available space according to a given [bias].
*/
@Stable
fun Packed(bias: Float) = ChainStyle(SolverChain.PACKED, bias)
}
}
Box(
modifier = Modifier
.size(10.dp)
.background(Color.Red)
.constrainAs(box1) {
top.linkTo(parent.top)
start.linkTo(parent.start)
}
)
Box(
modifier = Modifier
.size(10.dp)
.background(Color.Yellow)
.constrainAs(box2) {
start.linkTo(box1.end)
}
)
Box(
modifier = Modifier
.size(10.dp)
.background(Color.Green)
.constrainAs(box3) {
start.linkTo(box2.start)
}
)
createHorizontalChain(box1, box2, box3, chainStyle = ChainStyle.SpreadInside)
코드 1을 위와 같이 수정하여 사용할 수 있다.
createHorizontalChain에 chainStyle을 넣어 사용한다.
2. Barrier
여러 컴포저블을 참고하여 가장 극단적인 위젯을 기반으로 가상 가이드라인을 만드는 것
createTopBarrier, createBottomBarrier, createEndBarrier, createStartBarrier를 사용
예를 들어 chain의 예시 사진 처럼 상자가 3개가 있고 top으로 부터 위치가 각각 다를 때 가장 아래의 box에 글을 추가하고 싶다면 어떻게 해야할까?
val (box1, box2, box3, text) = createRefs()
Box(
modifier = Modifier
.size(10.dp)
.background(Color.Red)
.constrainAs(box1) {
top.linkTo(parent.top)
start.linkTo(parent.start)
}
)
Box(
modifier = Modifier
.size(10.dp)
.background(Color.Yellow)
.constrainAs(box2) {
top.linkTo(parent.top, margin = 10.dp)
start.linkTo(box1.end)
}
)
Box(
modifier = Modifier
.size(10.dp)
.background(Color.Green)
.constrainAs(box3) {
top.linkTo(parent.top, margin = 20.dp)
start.linkTo(box2.start)
}
)
createHorizontalChain(box1, box2, box3, chainStyle = ChainStyle.Spread)
val barrier = createBottomBarrier(box1, box2, box3)
Text(
text = "여기가 최하단",
fontSize = 10.sp,
modifier = Modifier.constrainAs(text) {
top.linkTo(barrier)
}
)
코드 1을 이렇게 수정해보면 좌측의 사진처럼 나오게 된다.
글씨가 아래 부분에 나오기 때문에 createBottomBarrier를 통해 box1~3을 넣고 top에 각각 margin을 줘 값을 다르게 하면 가장 하단인 것을 찾아 그 아래에 barrier가 생기게 된다.
그 barrier를 Text의 top에 넣게 되면, box1~3의 위치가 변경됨에 따라 barrier의 위치도 바뀌므로 Text의 위치가 자동으로 바뀌게 된다!
이런식으로 top, start, end, bottom에 원하는 대로 barrier를 만들어 사용할 수 있다.
fun createBottomBarrier(
vararg elements: ConstrainedLayoutReference,
margin: Dp = 0.dp
): HorizontalAnchor {
val id = createHelperId()
tasks.add { state ->
state.barrier(id, SolverDirection.BOTTOM).apply {
add(*(elements.map { it.id }.toTypedArray()))
}.margin(state.convertDimension(margin))
}
updateHelpersHashCode(15)
elements.forEach { updateHelpersHashCode(it.hashCode()) }
updateHelpersHashCode(margin.hashCode())
return HorizontalAnchor(id, 0)
}
또한 Barrier에는 margin 값을 넣을 수 있기 때문에 원하는 대로 margin 값을 줄 수 있다.
val barrier = createBottomBarrier(box1, box2, box3, margin = 10.dp)
[참고 및 출처]
Compose의 ConstraintLayout | Jetpack Compose | Android Developers
Compose의 ConstraintLayout 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. ConstraintLayout은 화면에 다른 컴포저블을 기준으로 컴포저블을 배치할 수 있는 레이아웃
developer.android.com
ConstraintLayout | Android Developers
Stay organized with collections Save and categorize content based on your preferences. ConstraintLayout This package is part of the Android support library which is no longer maintained. The Constraint Layout support library has been superseded by the Andr
developer.android.com
'개발 공부 > 안드로이드' 카테고리의 다른 글
[Compose] 컴포즈 공부하기 7 - Snackbar (0) | 2023.09.11 |
---|---|
[Compose] 컴포즈 공부하기 6 - Scaffold (0) | 2023.09.07 |
[Compose] 컴포즈 공부하기5 - ConstraintLayout 1 (0) | 2023.09.06 |
[Compose] 컴포즈 공부하기4 - Image (with painter) (0) | 2023.08.30 |
StateFlow에 대해 알아보자! (with LiveData) (0) | 2023.08.23 |